【实例简介】
【实例截图】
【核心代码】
package com.cloud.gateway.controller;
import com.cloud.gateway.feign.LogClient;
import com.cloud.gateway.feign.Oauth2Client;
import com.cloud.model.log.Log;
import com.cloud.model.oauth.SystemClientInfo;
import com.cloud.model.user.constants.CredentialType;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.util.OAuth2Utils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
/**
* 登陆、刷新token、退出
*
* author 小威老师
*/
Slf4j
RestController
public class TokenController {
Autowired
private Oauth2Client oauth2Client;
/**
* 系统登陆
* 根据用户名登录
* 采用oauth2密码模式获取access_token和refresh_token
*
* param username
* param password
* return
*/
PostMapping("/sys/login")
public Map login(String username, String password) {
Map parameters new HashMap();
parameters.put(OAuth2Utils.GRANT_TYPE, "password");
parameters.put(OAuth2Utils.CLIENT_ID, SystemClientInfo.CLIENT_ID);
parameters.put("client_secret", SystemClientInfo.CLIENT_SECRET);
parameters.put(OAuth2Utils.SCOPE, SystemClientInfo.CLIENT_SCOPE);
//parameters.put("username", username);
// 为了支持多类型登录这里在username后拼装上登录类型
parameters.put("username", username "|" CredentialType.USERNAME.name());
parameters.put("password", password);
Map tokenInfo oauth2Client.postAccessToken(parameters);
saveLoginLog(username, "用户名密码登陆");
return tokenInfo;
}
/**
* 短信登录
*
* param phone
* param key
* param code
* return
*/
PostMapping("/sys/login-sms")
public Map smsLogin(String phone, String key, String code) {
Map parameters new HashMap();
parameters.put(OAuth2Utils.GRANT_TYPE, "password");
parameters.put(OAuth2Utils.CLIENT_ID, SystemClientInfo.CLIENT_ID);
parameters.put("client_secret", SystemClientInfo.CLIENT_SECRET);
parameters.put(OAuth2Utils.SCOPE, SystemClientInfo.CLIENT_SCOPE);
// 为了支持多类型登录这里在username后拼装上登录类型同时为了校验短信验证码我们也拼上code等
parameters.put("username", phone "|" CredentialType.PHONE.name() "|" key "|" code "|"
DigestUtils.md5Hex(key code));
// 短信登录无需密码但security底层有密码校验我们这里将手机号作为密码认证中心采用同样规则即可
parameters.put("password", phone);
Map tokenInfo oauth2Client.postAccessToken(parameters);
saveLoginLog(phone, "手机号短信登陆");
return tokenInfo;
}
/**
* 微信登录
*
* return
*/
PostMapping("/sys/login-wechat")
public Map smsLogin(String openid, String tempCode) {
Map parameters new HashMap();
parameters.put(OAuth2Utils.GRANT_TYPE, "password");
parameters.put(OAuth2Utils.CLIENT_ID, SystemClientInfo.CLIENT_ID);
parameters.put("client_secret", SystemClientInfo.CLIENT_SECRET);
parameters.put(OAuth2Utils.SCOPE, SystemClientInfo.CLIENT_SCOPE);
// 为了支持多类型登录这里在username后拼装上登录类型同时为了服务端校验我们也拼上tempCode
parameters.put("username", openid "|" CredentialType.WECHAT_OPENID.name() "|" tempCode);
// 微信登录无需密码但security底层有密码校验我们这里将手机号作为密码认证中心采用同样规则即可
parameters.put("password", tempCode);
Map tokenInfo oauth2Client.postAccessToken(parameters);
saveLoginLog(openid, "微信登陆");
return tokenInfo;
}
Autowired
private LogClient logClient;
/**
* 登陆日志
*
* param username
*/
private void saveLoginLog(String username, String remark) {
log.info("{}登陆", username);
// 异步
CompletableFuture.runAsync(() -> {
try {
Log log Log.builder().username(username).module("登陆").remark(remark).createTime(new Date())
.build();
logClient.save(log);
} catch (Exception e) {
// do nothing
}
});
}
/**
* 系统刷新refresh_token
*
* param refresh_token
* return
*/
PostMapping("/sys/refresh_token")
public Map refresh_token(String refresh_token) {
Map parameters new HashMap();
parameters.put(OAuth2Utils.GRANT_TYPE, "refresh_token");
parameters.put(OAuth2Utils.CLIENT_ID, SystemClientInfo.CLIENT_ID);
parameters.put("client_secret", SystemClientInfo.CLIENT_SECRET);
parameters.put(OAuth2Utils.SCOPE, SystemClientInfo.CLIENT_SCOPE);
parameters.put("refresh_token", refresh_token);
return oauth2Client.postAccessToken(parameters);
}
/**
* 退出
*
* param access_token
*/
GetMapping("/sys/logout")
public void logout(String access_token, RequestHeader(required false, value "Authorization") String token) {
if (StringUtils.isBlank(access_token)) {
if (StringUtils.isNoneBlank(token)) {
access_token token.substring(OAuth2AccessToken.BEARER_TYPE.length() 1);
}
}
oauth2Client.removeToken(access_token);
}
}