在分布式环境中,如何支持PC、APP(ios、android)等多端的会话共享,这也是所有公司都需要的解决方案,用传统的session方式来解决,我想已经out了,我们是否可以找一个通用的方案,比如用传统cas来实现多系统之间的sso单点登录或使用oauth的第三方登录方案? 今天给大家简单讲解一下使用spring拦截器Interceptor机制、jwt认证方式、redis分布式缓存实现sso单点登录,闲话少说,直接把步骤记录下来分享给大家:
1. 引入jwt的相关jar包,在项目pom.xml中引入:
Java代码
com.auth0
java-jwt
2.2.0
[java]view plaincopyprint?
com.auth0
java-jwt
2.2.0
com.auth0
java-jwt
2.2.0
2. 拦截器配置:
Java代码
[java]view plaincopyprint?
我这里简单配置了要拦截的url和过滤的url(这个根据自己项目来定)
3. 编写jwt的加密或者解密工具类:
Java代码
publicclass JWT {
privatestaticfinal String SECRET ="HONGHUJWT1234567890QWERTYUIOPASDFGHJKLZXCVBNM";
privatestaticfinal String EXP ="exp";
privatestaticfinal String PAYLOAD ="payload";
//加密
publicstatic String sign(T object,long maxAge) {
try {
final JWTSigner signer =new JWTSigner(SECRET);
final Map claims =new HashMap();
ObjectMapper mapper =new ObjectMapper();
String jsonString = mapper.writeValueAsString(object);
claims.put(PAYLOAD, jsonString);
claims.put(EXP, System.currentTimeMillis() + maxAge);
return signer.sign(claims);
}catch(Exception e) {
returnnull;
}
}
//解密
publicstatic T unsign(String jwt, Class classT) {
final JWTVerifier verifier =new JWTVerifier(SECRET);
try {
final Map claims= verifier.verify(jwt);
if (claims.containsKey(EXP) && claims.containsKey(PAYLOAD)) {
String json = (String)claims.get(PAYLOAD);
ObjectMapper objectMapper =new ObjectMapper();
return objectMapper.readValue(json, classT);
}
returnnull;
}catch (Exception e) {
returnnull;
}
}
}
[java]view plaincopyprint?
publicclass JWT {
privatestaticfinal String SECRET ="HONGHUJWT1234567890QWERTYUIOPASDFGHJKLZXCVBNM";
privatestaticfinal String EXP ="exp";
privatestaticfinal String PAYLOAD ="payload";
//加密
publicstatic String sign(T object,long maxAge) {
try {
final JWTSigner signer =new JWTSigner(SECRET);
final Map claims =new HashMap();
ObjectMapper mapper =new ObjectMapper();
String jsonString = mapper.writeValueAsString(object);
claims.put(PAYLOAD, jsonString);
claims.put(EXP, System.currentTimeMillis() + maxAge);
return signer.sign(claims);
}catch(Exception e) {
returnnull;
}
}
//解密
publicstatic T unsign(String jwt, Class classT) {
final JWTVerifier verifier =new JWTVerifier(SECRET);
try {
final Map claims= verifier.verify(jwt);
if (claims.containsKey(EXP) && claims.containsKey(PAYLOAD)) {
String json = (String)claims.get(PAYLOAD);
ObjectMapper objectMapper =new ObjectMapper();
return objectMapper.readValue(json, classT);
}
returnnull;
}catch (Exception e) {
returnnull;
}
}
}
public class JWT {
private static final String SECRET = "HONGHUJWT1234567890QWERTYUIOPASDFGHJKLZXCVBNM";
private static final String EXP = "exp";
private static final String PAYLOAD = "payload";
//加密
public static String sign(T object, long maxAge) {
try {
final JWTSigner signer = new JWTSigner(SECRET);
final Map claims = new HashMap();
ObjectMapper mapper = new ObjectMapper();
String jsonString = mapper.writeValueAsString(object);
claims.put(PAYLOAD, jsonString);
claims.put(EXP, System.currentTimeMillis() + maxAge);
return signer.sign(claims);
} catch(Exception e) {
return null;
}
}
//解密
public static T unsign(String jwt, Class classT) {
final JWTVerifier verifier = new JWTVerifier(SECRET);
try {
final Map claims= verifier.verify(jwt);
if (claims.containsKey(EXP) && claims.containsKey(PAYLOAD)) {
String json = (String)claims.get(PAYLOAD);
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(json, classT);
}
return null;
} catch (Exception e) {
return null;
}
}
}
这个加密工具类是我从网上找的,如果各位要修改,可以按照自己业务修改即可。
4. 创建Login.java对象,用来进行jwt的加密或者解密:
Java代码
publicclass Loginimplements Serializable{
/**
*
*/
privatestaticfinallong serialVersionUID = 1899232511233819216L;
/**
* 用户id
*/
private String uid;
/**
* 登录用户名
*/
private String loginName;
/**
* 登录密码
*/
private String password;
public Login(){
super();
}
public Login(String uid, String loginName, String password){
this.uid = uid;
this.loginName = loginName;
this.password = password;
}
public String getUid() {
return uid;
}
publicvoid setUid(String uid) {
this.uid = uid;
}
public String getLoginName() {
return loginName;
}
publicvoid setLoginName(String loginName) {
this.loginName = loginName;
}
public String getPassword() {
return password;
}
publicvoid setPassword(String password) {
this.password = password;
}
}
[java]view plaincopyprint?
publicclass Loginimplements Serializable{
/**
*
*/
privatestaticfinallong serialVersionUID = 1899232511233819216L;
/**
* 用户id
*/
private String uid;
/**
* 登录用户名
*/
private String loginName;
/**
* 登录密码
*/
private String password;
public Login(){
super();
}
public Login(String uid, String loginName, String password){
this.uid = uid;
this.loginName = loginName;
this.password = password;
}
public String getUid() {
return uid;
}
publicvoid setUid(String uid) {
this.uid = uid;
}
public String getLoginName() {
return loginName;
}
publicvoid setLoginName(String loginName) {
this.loginName = loginName;
}
public String getPassword() {
return password;
}
publicvoid setPassword(String password) {
this.password = password;
}
}
public class Login implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1899232511233819216L;
/**
* 用户id
*/token;
}
愿意了解框架技术或者源码的朋友直接求求交流分享技术:3133806896
分布式的一些解决方案,有愿意了解的朋友可以找我们团队探讨
更多详细源码参考来源