单点登陆(Single Sign On)
在分布式的微服务架构中,存在多台服务器,在某一台服务器进行登陆后,多台服务器可同时检测到登陆状态
三种方式
①Session广播机制
实质为session的复制
②cookie+redis实现
将登陆后的数据放置到redis中,将其key存储到cookie中
③使用token是实现(令牌机制)
Token
按照一定的规则生成字符串,可包含用户信息:
JWT头信息+有效载荷(主体部分)+签名哈希(防伪标志)
将生成的字符串返回给客户端,每次访问可携带token
借助token实现单点登陆过程
①客户端在进行登陆访问后,服务端生成token字符串返回给客户端
②客户端在之后的每次访问请求中都会携带token(可放在head或cookie中)
③服务器解析token可判断登陆状态
使用jwt生成TokenUtils
/**
*使用jwt算法生成token字符串
*/
public class JwtUtils {
//常量
public static final long EXPIRE = 1000 * 60 * 60 * 24; //token过期时间
public static final String APP_SECRET = "ukc8BDbRigUDaY6pZFfWus2jZWLPHO"; //秘钥
//生成token字符串的方法
public static String getJwtToken(String id, String nickname){
String JwtToken = ()
//头信息
.setHeaderParam("typ", "JWT")
.setHeaderParam("alg", "HS256")
//设置过期时间
.setSubject("online-user")
.setIssuedAt(new Date())
.setExpiration(new Date(() + EXPIRE))
//设置token主体部分 ,存储用户信息
.claim("id", id)
.claim("nickname", nickname)
//签名Hash
.signWith(SignatureAlgorithm.HS256, APP_SECRET)
.compact();
return JwtToken;
}
/**
* 判断token是否存在与有效
*/
public static boolean checkToken(String jwtToken) {
if((jwtToken)) return false;
try {
().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
} catch (Exception e) {
();
return false;
}
return true;
}
/**
* 判断token是否存在与有效
*/
public static boolean checkToken(HttpServletRequest request) {
try {
String jwtToken = ("token");
if((jwtToken)) return false;
().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
} catch (Exception e) {
();
return false;
}
return true;
}
/**
* 根据token字符串获取用户id
*/
public static String getMemberIdByJwtToken(HttpServletRequest request) {
String jwtToken = ("token");
if((jwtToken)) return "";
Jws<Claims> claimsJws = ().setSigningKey(APP_SECRET).parseClaimsJws(jwtToken);
Claims claims = ();
return (String)("id");
}
}