Spring boot集成token,接口对token进行校验,并使用token获取登录用户信息
1、缓存token、验证token信息
public void setTokenUser(String userId, String token) {
MapCache.single().set("tokenUser" + userId, token, 18000);
MapCache.single().set(token, getSysUser(), 18000);
}
public SysUser analyticalUser() {
String token = null;
try {
token = getRequest().getHeader("accessToken");
} catch (NoSuchMessageException e) {
throw new UserTokenInvalidException("10000", null, "无认证信息,请先登录");
}
if (token == null) {
throw new UserTokenInvalidException("10000", null, "无认证信息,请先登录");
}
SysUser user = MapCache.single().get(token);
if (user == null) {
throw new UserTokenInvalidException("10000", null, "认证失效,请先登录");
}
String tokenVerify = MapCache.single().get("tokenUser" + user.getUserId());
System.out.println(tokenVerify);
if (!tokenVerify.equals(token)) {
throw new UserTokenInvalidException("10000", null, "登录失效,请先登录");
}
MapCache.single().set("tokenUser" + user.getUserId(), token, 18000);
MapCache.single().set(token, user, 18000);
return user;
}
2、SysUser实体类
public class SysUser extends BaseEntity
{
private static final long serialVersionUID = 1L;
@Excel(name = "用户序号", cellType = ColumnType.NUMERIC, prompt = "用户编号")
private Long userId;
@Excel(name = "部门编号", type = Type.IMPORT)
private Long deptId;
private Long roleId;
@Excel(name = "登录名称")
private String loginName;
@Excel(name = "用户名称")
private String userName;
private String password;
private String salt;
@Excel(name = "帐号状态", readConverterExp = "0=正常,1=停用")
private String status;
private String delFlag;
private Date pwdUpdateDate;
public SysUser()
{
}
public SysUser(Long userId)
{
this.userId = userId;
}
}
3、Map缓存实现工具类
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class MapCache {
private static final int DEFAULT_CACHES = 1024;
private static final MapCache INS = new MapCache();
public static MapCache single() {
return INS;
}
private final Map<String, CacheObject> cachePool;
public MapCache() {
this(DEFAULT_CACHES);
}
public MapCache(int cacheCount) {
cachePool = new ConcurrentHashMap<>(cacheCount);
}
public <T> T get(String key) {
CacheObject cacheObject = cachePool.get(key);
if (null != cacheObject) {
long cur = System.currentTimeMillis() / 1000;
if (cacheObject.getExpired() <= 0 || cacheObject.getExpired() > cur) {
Object result = cacheObject.getValue();
return (T) result;
}
}
return null;
}
public <T> T hget(String key, String field) {
key = key + ":" + field;
return this.get(key);
}
public void set(String key, Object value) {
this.set(key, value, -1);
}
public void set(String key, Object value, long expired) {
expired = expired > 0 ? System.currentTimeMillis() / 1000 + expired : expired;
CacheObject cacheObject = new CacheObject(key, value, expired);
cachePool.put(key, cacheObject);
}
public void hset(String key, String field, Object value) {
this.hset(key, field, value, -1);
}
public void hset(String key, String field, Object value, long expired) {
key = key + ":" + field;
expired = expired > 0 ? System.currentTimeMillis() / 1000 + expired : expired;
CacheObject cacheObject = new CacheObject(key, value, expired);
cachePool.put(key, cacheObject);
}
public void del(String key) {
cachePool.remove(key);
}
public void hdel(String key, String field) {
key = key + ":" + field;
this.del(key);
}
public void clean() {
cachePool.clear();
}
static class CacheObject {
private final String key;
private final Object value;
private final long expired;
public CacheObject(String key, Object value, long expired) {
this.key = key;
this.value = value;
this.expired = expired;
}
public String getKey() {
return key;
}
public Object getValue() {
return value;
}
public long getExpired() {
return expired;
}
}
}
4、自定义异常类
import com.common.exception.base.BaseException;
public class UserTokenInvalidException extends BaseException
{
private static final long serialVersionUID = 1L;
public UserTokenInvalidException(String code, Object[] args, String message)
{
super("user token invalid", code, args, message);
}
}
5、shiro 工具类
public class ShiroUtils
{
public static Subject getSubject()
{
return SecurityUtils.getSubject();
}
public static Session getSession()
{
return SecurityUtils.getSubject().getSession();
}
public static void logout()
{
getSubject().logout();
}
public static SysUser getSysUser()
{
SysUser user = null;
Object obj = getSubject().getPrincipal();
if (StringUtils.isNotNull(obj))
{
user = new SysUser();
BeanUtils.copyBeanProp(user, obj);
}
return user;
}
public static void setSysUser(SysUser user)
{
Subject subject = getSubject();
PrincipalCollection principalCollection = subject.getPrincipals();
String realmName = principalCollection.getRealmNames().iterator().next();
PrincipalCollection newPrincipalCollection = new SimplePrincipalCollection(user, realmName);
subject.runAs(newPrincipalCollection);
}
public static Long getUserId()
{
return getSysUser().getUserId().longValue();
}
public static String getLoginName()
{
return getSysUser().getLoginName();
}
public static String getIp()
{
return getSubject().getSession().getHost();
}
public static String getSessionId()
{
return String.valueOf(getSubject().getSession().getId());
}
public static String randomSalt()
{
SecureRandomNumberGenerator secureRandom = new SecureRandomNumberGenerator();
String hex = secureRandom.nextBytes(3).toHex();
return hex;
}
}
6、登录 and 后端解析用户信息
@PostMapping("/login")
@ResponseBody
public AjaxResult login(@NotNull(message = "用户不能为空!")String username,
@NotNull(message = "密码不能为空!")String password ,
HttpServletRequest request) throws IOException {
System.out.println("pad登录>>>>userName>>>"+username+">>>password>>>"+password);
UsernamePasswordToken token = new UsernamePasswordToken(username, password, false);
Subject subject = SecurityUtils.getSubject();
try {
subject.login(token);
loginDto dto = new loginDto();
dto.setUserId(getUserId().toString());
dto.setToken(UUID.randomUUID().toString());
System.out.println("【登录获取token】{}"+dto.getToken());
setTokenUser(dto.getUserId(),dto.getToken());
return AjaxResult.success(dto);
} catch (AuthenticationException e) {
String msg = "登录名或密码错误";
return error(msg);
}
}
@PostMapping("/getUser")
@ResponseBody
public AjaxResult getUser(){
System.out.println("【解析访问用户信息】");
SysUser user = analyticalUser();
return AjaxResult.success(user);
}
7、请求接口时,headers请求头带有accessToken参数
