在分布式环境中,如何支持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

分布式的一些解决方案,有愿意了解的朋友可以找我们团队探讨

更多详细源码参考来源