在分佈式環境中,如何支持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
分佈式的一些解決方案,有願意瞭解的朋友可以找我們團隊探討