今天就跟大家聊聊有關(guān)Springboot中怎么使用shiro和jwt實(shí)現(xiàn)前后端分離,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
創(chuàng)新互聯(lián)建站是一家專注于網(wǎng)站制作、成都網(wǎng)站建設(shè)與策劃設(shè)計(jì),封丘網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)建站做網(wǎng)站,專注于網(wǎng)站建設(shè)10多年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:封丘等地區(qū)。封丘做網(wǎng)站價(jià)格咨詢:028-86922220
先下載shiro和jwt的jar包
<!-- shiro包 --><dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring</artifactId> <version>1.4.0</version></dependency><dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-ehcache</artifactId> <version>1.4.0</version></dependency><!--JWT依賴--><!--JWT--><dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.4.0</version></dependency><!--JJWT--><dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.0</version></dependency>
創(chuàng)建shiro的自定義的Realm
代碼如下:
package com.serverprovider.config.shiro.userRealm; import com.spring.common.auto.autoUser.AutoUserModel;import com.spring.common.auto.autoUser.extend.AutoModelExtend;import com.serverprovider.config.shiro.jwt.JWTCredentialsMatcher;import com.serverprovider.config.shiro.jwt.JwtToken;import com.serverprovider.service.loginService.LoginServiceImpl;import com.util.redis.RedisUtil;import com.util.ReturnUtil.SecretKey;import com.util.encryption.JWTDecodeUtil;import io.jsonwebtoken.Claims;import org.apache.log4j.Logger;import org.apache.shiro.authc.*;import org.apache.shiro.authz.AuthorizationInfo;import org.apache.shiro.authz.SimpleAuthorizationInfo;import org.apache.shiro.realm.AuthorizingRealm;import org.apache.shiro.subject.PrincipalCollection;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.ExceptionHandler; import java.util.HashSet;import java.util.List;import java.util.Set; public class UserRealm extends AuthorizingRealm { private Logger logger = Logger.getLogger(UserRealm.class); @Autowired private LoginServiceImpl loginService; public UserRealm(){ //這里使用我們自定義的Matcher驗(yàn)證接口 this.setCredentialsMatcher(new JWTCredentialsMatcher()); } /** * 必須重寫(xiě)此方法,不然Shiro會(huì)報(bào)錯(cuò) */ @Override public boolean supports(AuthenticationToken token) { return token instanceof JwtToken; } /** * shiro 身份驗(yàn)證 * @param token * @return boolean * @throws AuthenticationException 拋出的異常將有統(tǒng)一的異常處理返回給前端 * */ @Override protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)throws AuthenticationException { /** * AuthenticationToken * JwtToken重寫(xiě)了AuthenticationToken接口 并創(chuàng)建了一個(gè)接口token的變量 * 因?yàn)樵趂ilter我們將token存入了JwtToken的token變量中 * 所以這里直接getToken()就可以獲取前端傳遞的token值 */ String JWTtoken = ((JwtToken) token).getToken(); /** * Claims對(duì)象它最終是一個(gè)JSON格式的對(duì)象,任何值都可以添加到其中 * token解密 轉(zhuǎn)換成Claims對(duì)象 */ Claims claims = JWTDecodeUtil.parseJWT(JWTtoken, SecretKey.JWTKey); /** * 根據(jù)JwtUtil加密方法加入的參數(shù)獲取數(shù)據(jù) * 查詢數(shù)據(jù)庫(kù)獲得對(duì)象 * 如為空:拋出異常 * 如驗(yàn)證失敗拋出 AuthorizationException */ String username = claims.getSubject(); String password = (String) claims.get("password"); AutoModelExtend principal = loginService.selectLoginModel(username,password); return new SimpleAuthenticationInfo(principal, JWTtoken,"userRealm"); } @Override protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { SimpleAuthorizationInfo info = null; /** * PrincipalCollection對(duì)象 * 文檔里面描述:返回從指定的Realm 僅作為Collection 返回的單個(gè)Subject的對(duì)象,如果沒(méi)有來(lái)自該領(lǐng)域的任何對(duì)象,則返回空的Collection。 * 在登錄接口放入權(quán)限注解返回的錯(cuò)誤信息:Subject.login(AuthenticationToken)或SecurityManager啟用'Remember Me'功能后成功自動(dòng)獲取這些標(biāo)識(shí)主體 * 當(dāng)調(diào)用Subject.login()方法成功后 PrincipalCollection會(huì)自動(dòng)獲得該對(duì)象 如沒(méi)有認(rèn)證過(guò)或認(rèn)證失敗則返回空的Collection并拋出異常 * getPrimaryPrincipal():返回在應(yīng)用程序范圍內(nèi)使用的主要對(duì)象,以唯一標(biāo)識(shí)擁有帳戶。 */ Object principal = principals.getPrimaryPrincipal(); /** * 得到身份對(duì)象 * 查詢?cè)撚脩舻臋?quán)限信息 */ AutoUserModel user = (AutoUserModel) principal; List<String> roleModels = loginService.selectRoleDetails(user.getId()); try { /** * 創(chuàng)建一個(gè)Set,來(lái)放置用戶擁有的權(quán)限 * 創(chuàng)建 SimpleAuthorizationInfo, 并將辦好權(quán)限列表的Set放入. */ Set<String> rolesSet = new HashSet(); for (String role : roleModels) { rolesSet.add(role); } info = new SimpleAuthorizationInfo(); info.setStringPermissions(rolesSet); // 放入權(quán)限信息 }catch (Exception e){ throw new AuthenticationException("授權(quán)失敗!"); } return info; }}
這個(gè)授權(quán)方法遇到的坑比較少,就是在最終驗(yàn)證的時(shí)候網(wǎng)上很照抄過(guò)來(lái)的帖子一點(diǎn)都沒(méi)有驗(yàn)證就粘貼賦值,在這里嚴(yán)重吐槽。
在使用jwt最為token而取消shiro傳統(tǒng)的session時(shí)候,我們的需要重寫(xiě)shiro的驗(yàn)證接口 CredentialsMatcher,在 自定義的realm
中我們加入我們重寫(xiě)的驗(yàn)證方法,在調(diào)用SimpleAuthenticationInfo()方法進(jìn)行驗(yàn)證的時(shí)候,shiro就會(huì)使用重寫(xiě)的驗(yàn)證接口。
此處為大坑。
貼上代碼如下:
import com.spring.common.auto.autoUser.extend.AutoModelExtend;import org.apache.log4j.Logger;import org.apache.shiro.authc.AuthenticationInfo;import org.apache.shiro.authc.AuthenticationToken;import org.apache.shiro.authc.credential.CredentialsMatcher; /** * CredentialsMatcher * 接口由類實(shí)現(xiàn),該類可以確定是否提供了AuthenticationToken憑證與系統(tǒng)中存儲(chǔ)的相應(yīng)帳戶的憑證相匹配。 * Shiro 加密匹配 重寫(xiě)匹配方法CredentialsMatcher 使用JWTUtil 匹配方式 */public class JWTCredentialsMatcher implements CredentialsMatcher { private Logger logger = Logger.getLogger(JWTCredentialsMatcher.class); /** * Matcher中直接調(diào)用工具包中的verify方法即可 */ @Override public boolean doCredentialsMatch(AuthenticationToken authenticationToken, AuthenticationInfo authenticationInfo) { String token = (String) ((JwtToken)authenticationToken).getToken(); AutoModelExtend user = (AutoModelExtend)authenticationInfo.getPrincipals().getPrimaryPrincipal(); //得到DefaultJwtParser Boolean verify = JwtUtil.isVerify(token, user); logger.info("JWT密碼效驗(yàn)結(jié)果="+verify); return verify; }}
shiro的配置項(xiàng) ShiroConfiguration代碼如下:
import com.serverprovider.config.shiro.shiroSysFile.JwtFilter;import com.serverprovider.config.shiro.userRealm.UserRealm;import org.apache.log4j.Logger;import org.apache.shiro.mgt.DefaultSessionStorageEvaluator;import org.apache.shiro.mgt.DefaultSubjectDAO;import org.apache.shiro.mgt.SecurityManager;import org.apache.shiro.mgt.SessionStorageEvaluator;import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;import org.apache.shiro.spring.web.ShiroFilterFactoryBean;import org.apache.shiro.web.mgt.DefaultWebSecurityManager;import org.apache.shiro.web.mgt.DefaultWebSessionStorageEvaluator; import org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration; import javax.servlet.Filter;import java.util.*; @Configurationpublic class ShiroConfiguration { private Logger logger = Logger.getLogger(ShiroConfiguration.class); @Bean("shiroFilter") public ShiroFilterFactoryBean shiroFilter(SecurityManager securityManager) { ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); shiroFilterFactoryBean.setSecurityManager(securityManager); //攔截器 Map<String, String> filterChainDefinitionMap = new LinkedHashMap<String, String>(); // 配置不會(huì)被攔截的鏈接 順序判斷 filterChainDefinitionMap.put("/login/**", "anon"); // 添加自己的過(guò)濾器并且取名為jwt Map<String, Filter> filterMap = new HashMap<String, Filter>(); filterMap.put("jwt", new JwtFilter()); shiroFilterFactoryBean.setFilters(filterMap); //<!-- 過(guò)濾鏈定義,從上向下順序執(zhí)行,一般將/**放在最為下邊 filterChainDefinitionMap.put("/**", "jwt"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); return shiroFilterFactoryBean; } /** * 禁用session, 不保存用戶登錄狀態(tài)。保證每次請(qǐng)求都重新認(rèn)證。 * 需要注意的是,如果用戶代碼里調(diào)用Subject.getSession()還是可以用session */ @Bean protected SessionStorageEvaluator sessionStorageEvaluator(){ DefaultWebSessionStorageEvaluator sessionStorageEvaluator = new DefaultWebSessionStorageEvaluator(); sessionStorageEvaluator.setSessionStorageEnabled(false); return sessionStorageEvaluator; } @Bean("securityManager") public SecurityManager securityManager(UserRealm userRealm) { DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); securityManager.setRealm(userRealm); /* * 關(guān)閉shiro自帶的session,詳情見(jiàn)文檔 * http://shiro.apache.org/session-management.html#SessionManagement-StatelessApplications%28Sessionless%29 */ DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO(); DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator(); defaultSessionStorageEvaluator.setSessionStorageEnabled(false); subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator); securityManager.setSubjectDAO(subjectDAO); return securityManager; } /** * 創(chuàng)建自定義的UserRealm @bean */ @Bean("userRealm") public UserRealm shiroRealm() { UserRealm shiroRealm = new UserRealm(); return shiroRealm; } //自動(dòng)創(chuàng)建代理,沒(méi)有這個(gè)鑒權(quán)可能會(huì)出錯(cuò) @Bean public DefaultAdvisorAutoProxyCreator getDefaultAdvisorAutoProxyCreator() { DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator(); autoProxyCreator.setProxyTargetClass(true); return autoProxyCreator; } /** * 開(kāi)啟shiro aop注解支持. * 使用代理方式;所以需要開(kāi)啟代碼支持; * * @param * @return */ @Bean public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(SecurityManager securityManager) { AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor = new AuthorizationAttributeSourceAdvisor(); authorizationAttributeSourceAdvisor.setSecurityManager(securityManager); return authorizationAttributeSourceAdvisor; }
到這里shiro配置就全部完成了
下面開(kāi)始配置jwt:
首先我們需要重寫(xiě) AuthenticationToken接口 此接口的作用
負(fù)責(zé)把shiro中username,password生成用于驗(yàn)證的token的封裝類
所有我們需要去實(shí)現(xiàn)這個(gè)接口,封裝我們自己生成的JWT生成的token
import org.apache.shiro.authc.AuthenticationToken; /** * AuthenticationToken: shiro中負(fù)責(zé)把username,password生成用于驗(yàn)證的token的封裝類 * 我們需要自定義一個(gè)對(duì)象用來(lái)包裝token。 */public class JwtToken implements AuthenticationToken { private String token; public JwtToken(String token) { this.token = token; } public String getToken() { return token; } public void setToken(String token) { this.token = token; } @Override public Object getPrincipal() { return null; } @Override public Object getCredentials() { return null; }}
因?yàn)槲覀兪乔昂蠖朔蛛x項(xiàng)目所有我們不存在session驗(yàn)證之類的 所有每次請(qǐng)求都需要攜帶token,所以每次請(qǐng)求我們都需要去驗(yàn)證token的真實(shí)性,所有我們需要去實(shí)現(xiàn) BasicHttpAuthenticationFilter過(guò)濾器
BasicHttpAuthenticationFilter繼承 AuthenticatingFilter 過(guò)濾器其能夠自動(dòng)地進(jìn)行基于所述傳入請(qǐng)求的認(rèn)證嘗試。此實(shí)現(xiàn)是每個(gè)基本HTTP身份驗(yàn)證規(guī)范的Java實(shí)現(xiàn) ,通過(guò)此過(guò)濾器得到HTTP請(qǐng)求資源獲取Authorization傳遞過(guò)來(lái)的token參數(shù) 獲取subject對(duì)象進(jìn)行身份驗(yàn)證
代碼如下:
import com.alibaba.fastjson.JSONObject;import com.serverprovider.config.shiro.jwt.JwtToken;import com.util.Util.utilTime;import org.apache.log4j.Logger;import org.apache.shiro.subject.Subject;import org.apache.shiro.web.filter.authc.BasicHttpAuthenticationFilter;import org.springframework.http.HttpStatus;import org.springframework.web.bind.annotation.ExceptionHandler;import org.springframework.web.bind.annotation.RequestMethod;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.io.PrintWriter;import java.util.concurrent.TimeUnit; /** * * BasicHttpAuthenticationFilter繼承 AuthenticatingFilter 過(guò)濾器 * 其能夠自動(dòng)地進(jìn)行基于所述傳入請(qǐng)求的認(rèn)證嘗試。 * BasicHttpAuthenticationFilter 基本訪問(wèn)認(rèn)證過(guò)濾器 * 此實(shí)現(xiàn)是每個(gè)基本HTTP身份驗(yàn)證規(guī)范的Java實(shí)現(xiàn) * 通過(guò)此過(guò)濾器得到HTTP請(qǐng)求資源獲取Authorization傳遞過(guò)來(lái)的token參數(shù) * 獲取subject對(duì)象進(jìn)行身份驗(yàn)證 * * */public class JwtFilter extends BasicHttpAuthenticationFilter { Logger logger = Logger.getLogger(JwtFilter.class); /** * 應(yīng)用的HTTP方法列表配置基本身份驗(yàn)證篩選器。 * 獲取 request 請(qǐng)求 拒絕攔截登錄請(qǐng)求 * 執(zhí)行登錄認(rèn)證方法 * * @param request * @param response * @param mappedValue * @return */ @Override protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) { HttpServletRequest httpServletRequest = (HttpServletRequest) request; String requestURI = httpServletRequest.getRequestURI(); if (requestURI.equals("/user/login/verifyUser") || requestURI.equals("/user/register")) { return true; } else { try { executeLogin(request, response); return true; } catch (Exception e) { e.printStackTrace(); return false; } } } /** * Authorization攜帶的參數(shù)為token * JwtToken實(shí)現(xiàn)了AuthenticationToken接口封裝了token參數(shù) * 通過(guò)getSubject方法獲取 subject對(duì)象 * login()發(fā)送身份驗(yàn)證 * * 為什么需要在Filter中調(diào)用login,不能在controller中調(diào)用login? * 由于Shiro默認(rèn)的驗(yàn)證方式是基于session的,在基于token驗(yàn)證的方式中,不能依賴session做為登錄的判斷依據(jù). * @param request * @param response */ @Override protected boolean executeLogin(ServletRequest request, ServletResponse response) throws Exception { HttpServletResponse httpServletResponse = (HttpServletResponse) response; try{ HttpServletRequest httpServletRequest = (HttpServletRequest) request; String token = httpServletRequest.getHeader("Authorization"); JwtToken jwtToken = new JwtToken(token); // 提交給realm進(jìn)行登入,如果錯(cuò)誤他會(huì)拋出異常并被捕獲 Subject subject = getSubject(request, response); subject.login(jwtToken); logger.info("JWT驗(yàn)證用戶信息成功"); // 如果沒(méi)有拋出異常則代表登入成功,返回true return true; }catch (Exception e){ /* * * 這個(gè)問(wèn)題糾結(jié)了好久 * 原生的shiro驗(yàn)證失敗會(huì)進(jìn)入全局異常 但是 和JWT結(jié)合以后卻不進(jìn)入了 之前一直想不通 * 原因是 JWT直接在過(guò)濾器里驗(yàn)證 驗(yàn)證成功與否 都是直接返回到過(guò)濾器中 成功在進(jìn)入controller * 失敗直接返回進(jìn)入springboot自定義異常處理頁(yè)面 */ JSONObject responseJSONObject = new JSONObject(); responseJSONObject.put("result","401"); responseJSONObject.put("resultCode","token無(wú)效,請(qǐng)重新獲取。"); responseJSONObject.put("resultData","null"); responseJSONObject.put("resultTime", utilTime.StringDate()); PrintWriter out = null; httpServletResponse.setCharacterEncoding("UTF-8"); httpServletResponse.setContentType("application/json; charset=utf-8"); logger.info("返回是"); logger.info(responseJSONObject.toString()); out = httpServletResponse.getWriter(); out.append(responseJSONObject.toString()); } return false; } /** * 對(duì)跨域提供支持 */ @Override protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception { HttpServletRequest httpServletRequest = (HttpServletRequest) request; HttpServletResponse httpServletResponse = (HttpServletResponse) response; httpServletResponse.setHeader("Access-control-Allow-Origin", httpServletRequest.getHeader("Origin")); httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS,PUT,DELETE"); httpServletResponse.setHeader("Access-Control-Allow-Headers", httpServletRequest.getHeader("Access-Control-Request-Headers")); // 跨域時(shí)會(huì)首先發(fā)送一個(gè)option請(qǐng)求,這里我們給option請(qǐng)求直接返回正常狀態(tài) if (httpServletRequest.getMethod().equals(RequestMethod.OPTIONS.name())) { httpServletResponse.setStatus(HttpStatus.OK.value()); return false; } return super.preHandle(request, response); } }
貼上 加密解密校驗(yàn)的工具類
import com.spring.common.auto.autoUser.extend.AutoModelExtend;import com.util.ReturnUtil.SecretKey;import io.jsonwebtoken.*;import java.util.Date;import java.util.HashMap;import java.util.Map;import java.util.UUID;; /* @author hw * @create 2019-04-16 10.12 * @desc JWT工具類 **/ public class JwtUtil { /** * 用戶登錄成功后生成Jwt * 使用Hs256算法 私匙使用用戶密碼 * * @param ttlMillis jwt過(guò)期時(shí)間 * @param user 登錄成功的user對(duì)象 * @return */ public static String createJWT(long ttlMillis, AutoModelExtend user) { //指定簽名的時(shí)候使用的簽名算法,也就是header那部分,jjwt已經(jīng)將這部分內(nèi)容封裝好了。 SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; //生成JWT的時(shí)間 long nowMillis = System.currentTimeMillis(); Date now = new Date(nowMillis); //創(chuàng)建payload的私有聲明(根據(jù)特定的業(yè)務(wù)需要添加,如果要拿這個(gè)做驗(yàn)證,一般是需要和jwt的接收方提前溝通好驗(yàn)證方式的) Map<String, Object> map = new HashMap<String, Object>(); map.put("id", user.getId()); map.put("username", user.getAuto_username()); map.put("password", user.getAuto_password()); //生成簽名的時(shí)候使用的秘鑰secret,這個(gè)方法本地封裝了的,一般可以從本地配置文件中讀取, // 切記這個(gè)秘鑰不能外露哦。它就是你服務(wù)端的私鑰,在任何場(chǎng)景都不應(yīng)該流露出去。一旦客戶端得知這個(gè)secret, 那就意味著客戶端是可以自我簽發(fā)jwt了。 String key = SecretKey.JWTKey; //生成簽發(fā)人 String subject = user.getAuto_username(); //下面就是在為payload添加各種標(biāo)準(zhǔn)聲明和私有聲明了 //這里其實(shí)就是new一個(gè)JwtBuilder,設(shè)置jwt的body JwtBuilder builder = Jwts.builder() //如果有私有聲明,一定要先設(shè)置這個(gè)自己創(chuàng)建的私有的聲明,這個(gè)是給builder的claim賦值,一旦寫(xiě)在標(biāo)準(zhǔn)的聲明賦值之后,就是覆蓋了那些標(biāo)準(zhǔn)的聲明的 .setClaims(map) //設(shè)置jti(JWT ID):是JWT的唯一標(biāo)識(shí),根據(jù)業(yè)務(wù)需要,這個(gè)可以設(shè)置為一個(gè)不重復(fù)的值,主要用來(lái)作為一次性token,從而回避重放攻擊。 .setId(UUID.randomUUID().toString()) //iat: jwt的簽發(fā)時(shí)間 .setIssuedAt(now) //代表這個(gè)JWT的主體,即它的所有人,這個(gè)是一個(gè)json格式的字符串,可以存放什么userid,roldid之類的,作為什么用戶的唯一標(biāo)志。 .setSubject(subject) //設(shè)置簽名使用的簽名算法和簽名使用的秘鑰 .signWith(signatureAlgorithm, key); if (ttlMillis >= 0) { long expMillis = nowMillis + ttlMillis; Date exp = new Date(expMillis); //設(shè)置過(guò)期時(shí)間 builder.setExpiration(exp); } return builder.compact(); } /** * 校驗(yàn)token * 在這里可以使用官方的校驗(yàn),我這里校驗(yàn)的是token中攜帶的密碼于數(shù)據(jù)庫(kù)一致的話就校驗(yàn)通過(guò) * * @param token * @return */ public static Boolean isVerify(String token, AutoModelExtend userModelExtend) { try { //得到DefaultJwtParser Claims claims = Jwts.parser() //設(shè)置簽名的秘鑰 .setSigningKey(SecretKey.JWTKey) //設(shè)置需要解析的jwt .parseClaimsJws(token).getBody(); if (claims.get("password").equals(userModelExtend.getAuto_password())) { return true; } } catch (Exception exception) { return false; } return null; } /** * Token的解密 * @param token 加密后的token * @param secret 簽名秘鑰,和生成的簽名的秘鑰一模一樣 * @return */ public static Claims parseJWT(String token, String secret) { //得到DefaultJwtParser Claims claims = Jwts.parser() //設(shè)置簽名的秘鑰 .setSigningKey(secret) //設(shè)置需要解析的jwt .parseClaimsJws(token).getBody(); return claims; }}
看完上述內(nèi)容,你們對(duì)Springboot中怎么使用shiro和jwt實(shí)現(xiàn)前后端分離有進(jìn)一步的了解嗎?如果還想了解更多知識(shí)或者相關(guān)內(nèi)容,請(qǐng)關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。
當(dāng)前題目:Springboot中怎么使用shiro和jwt實(shí)現(xiàn)前后端分離
標(biāo)題來(lái)源:http://bm7419.com/article40/jjsoho.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站營(yíng)銷、小程序開(kāi)發(fā)、網(wǎng)站收錄、服務(wù)器托管、電子商務(wù)、定制網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)