基于jwt的用户鉴权:拦截器概述
生活随笔
收集整理的這篇文章主要介紹了
基于jwt的用户鉴权:拦截器概述
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
基于攔截器的token與鑒權
如果我們每個方法都去寫一段代碼,冗余度太高,不利于維護,那如何做使我們的代碼看起來更清爽呢?我們可以將這段代碼放入攔截器去實現
Spring中的攔截器
Spring為我們提供了org.springframework.web.servlet.handler.HandlerInterceptorAdapter這個適配器,繼承此類,可以非常方便的實現自己的攔截器。他有三個方法:分別實現預處理、后處理(調用了Service并返回ModelAndView,但未進行頁面渲染)、返回處理(已經渲染了頁面)
1.在preHandle中,可以進行編碼、安全控制等處理; 2.在postHandle中,有機會修改ModelAndView; 3.在afterCompletion中,可以根據ex是否為null判斷是否發生了異常,進行日志記錄。
package com.learn.common.interceptor;import com.learn.common.entity.ResultCode; import com.learn.common.exception.CommonException; import com.learn.common.utils.JwtUtils; import io.jsonwebtoken.Claims; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;/*** 自定義攔截器* 繼承HandlerInterceptorAdapter** preHandle:進入到控制器方法之前執行的內容* boolean:* true:可以繼續執行控制器方法* false:攔截* posthandler:執行控制器方法之后執行的內容* afterCompletion:響應結束之前執行的內容** 1.簡化獲取token數據的代碼編寫* 統一的用戶權限校驗(是否登錄)* 2.判斷用戶是否具有當前訪問接口的權限**/ @Component public class JwtInterceptor extends HandlerInterceptorAdapter {/*** 簡化獲取token數據的代碼編寫(判斷是否登錄)* 1.通過request獲取請求token信息* 2.從token中解析獲取claims* 3.將claims綁定到request域中*/@Autowiredprivate JwtUtils jwtUtils;@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {// 1.通過request獲取請求token信息String authorization = request.getHeader("Authorization");//判斷請求頭信息是否為空,或者是否已Bearer開頭if(!StringUtils.isEmpty(authorization) && authorization.startsWith("Bearer")) {//獲取token數據String token = authorization.replace("Bearer ","");//解析token獲取claimsClaims claims = jwtUtils.parseJwt(token);if(claims != null) {//通過claims獲取到當前用戶的可訪問API權限字符串String apis = (String) claims.get("apis"); //api-user-delete,api-user-update//通過handlerHandlerMethod h = (HandlerMethod) handler;//獲取接口上的reqeustmapping注解RequestMapping annotation = h.getMethodAnnotation(RequestMapping.class);//獲取當前請求接口中的name屬性String name = annotation.name();//判斷當前用戶是否具有響應的請求權限if(apis.contains(name)) {request.setAttribute("user_claims",claims);return true;}else {throw new CommonException(ResultCode.UNAUTHORISE);}}}throw new CommonException(ResultCode.UNAUTHENTICATED);} } package com.learn.system.controller;import com.learn.common.controller.BaseController; import com.learn.common.entity.PageResult; import com.learn.common.entity.Result; import com.learn.common.entity.ResultCode;import com.learn.common.exception.CommonException; import com.learn.common.utils.JwtUtils; import com.learn.common.utils.PermissionConstants; import com.learn.domain.system.Permission; import com.learn.domain.system.Role; import com.learn.domain.system.response.ProfileResult; import com.learn.domain.system.User; import com.learn.domain.system.response.UserResult; import com.learn.system.service.PermissionService; import com.learn.system.service.RoleService; import com.learn.system.service.UserService; import io.jsonwebtoken.Claims; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpServletRequest; import java.util.HashMap; import java.util.List; import java.util.Map;//1.解決跨域 @CrossOrigin //2.聲明restContoller @RestController //3.設置父路徑 @RequestMapping(value="/sys") public class UserController extends BaseController {@Autowiredprivate UserService userService;@Autowiredprivate PermissionService permissionService;@Autowiredprivate JwtUtils jwtUtils;/*** 分配角色*/@RequestMapping(value = "/user/assignRoles", method = RequestMethod.PUT)public Result assignRoles(@RequestBody Map<String,Object> map) {//1.獲取被分配的用戶idString userId = (String) map.get("id");//2.獲取到角色的id列表List<String> roleIds = (List<String>) map.get("roleIds");//3.調用service完成角色分配userService.assignRoles(userId,roleIds);return new Result(ResultCode.SUCCESS);}/*** 保存*/@RequestMapping(value = "/user", method = RequestMethod.POST)public Result save(@RequestBody User user) {//1.設置保存的企業iduser.setCompanyId(companyId);user.setCompanyName(companyName);//2.調用service完成保存企業userService.save(user);//3.構造返回結果return new Result(ResultCode.SUCCESS);}/*** 查詢企業的部門列表* 指定企業id*/@RequestMapping(value = "/user", method = RequestMethod.GET)public Result findAll(int page, int size, @RequestParam Map map) {//1.獲取當前的企業idmap.put("companyId",companyId);//2.完成查詢Page<User> pageUser = userService.findAll(map,page,size);//3.構造返回結果PageResult pageResult = new PageResult(pageUser.getTotalElements(),pageUser.getContent());return new Result(ResultCode.SUCCESS, pageResult);}/*** 根據ID查詢user*/@RequestMapping(value = "/user/{id}", method = RequestMethod.GET)public Result findById(@PathVariable(value = "id") String id) {// 添加 roleIds (用戶已經具有的角色id數組)User user = userService.findById(id);UserResult userResult = new UserResult(user);return new Result(ResultCode.SUCCESS, userResult);}/*** 修改User*/@RequestMapping(value = "/user/{id}", method = RequestMethod.PUT)public Result update(@PathVariable(value = "id") String id, @RequestBody User user) {//1.設置修改的部門iduser.setId(id);//2.調用service更新userService.update(user);return new Result(ResultCode.SUCCESS);}/*** 根據id刪除*/@RequestMapping(value = "/user/{id}", method = RequestMethod.DELETE,name = "API-USER-DELETE")public Result delete(@PathVariable(value = "id") String id) {userService.deleteById(id);return new Result(ResultCode.SUCCESS);}/*** 用戶登錄* 1.通過service根據mobile查詢用戶* 2.比較password* 3.生成jwt信息**/@RequestMapping(value="/login",method = RequestMethod.POST)public Result login(@RequestBody Map<String,String> loginMap) {String mobile = loginMap.get("mobile");String password = loginMap.get("password");User user = userService.findByMobile(mobile);//登錄失敗if(user == null || !user.getPassword().equals(password)) {return new Result(ResultCode.MOBILEORPASSWORDERROR);}else {//登錄成功//api權限字符串StringBuilder sb = new StringBuilder();//獲取到所有的可訪問API權限for (Role role : user.getRoles()) {for (Permission perm : role.getPermissions()) {if(perm.getType() == PermissionConstants.PERMISSION_API) {sb.append(perm.getCode()).append(",");}}}Map<String,Object> map = new HashMap<>();map.put("apis",sb.toString());//可訪問的api權限字符串map.put("companyId",user.getCompanyId());map.put("companyName",user.getCompanyName());String token = jwtUtils.createJwt(user.getId(), user.getUsername(), map);return new Result(ResultCode.SUCCESS,token);}}/*** 用戶登錄成功之后,獲取用戶信息* 1.獲取用戶id* 2.根據用戶id查詢用戶* 3.構建返回值對象* 4.響應*/@RequestMapping(value="/profile",method = RequestMethod.POST)public Result profile(HttpServletRequest request) throws Exception {String userid = claims.getId();//獲取用戶信息User user = userService.findById(userid);//根據不同的用戶級別獲取用戶權限ProfileResult result = null;if("user".equals(user.getLevel())) {result = new ProfileResult(user);}else {Map map = new HashMap();if("coAdmin".equals(user.getLevel())) {map.put("enVisible","1");}List<Permission> list = permissionService.findAll(map);result = new ProfileResult(user,list);}return new Result(ResultCode.SUCCESS,result);} } package com.learn.common.controller;import io.jsonwebtoken.Claims; import org.springframework.web.bind.annotation.ModelAttribute;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;public class BaseController {protected HttpServletRequest request;protected HttpServletResponse response;protected String companyId;protected String companyName;protected Claims claims;@ModelAttributepublic void setResAnReq(HttpServletRequest request,HttpServletResponse response) {this.request = request;this.response = response;Object obj = request.getAttribute("user_claims");if(obj != null) {this.claims = (Claims) obj;this.companyId = (String)claims.get("companyId");this.companyName = (String)claims.get("companyName");}}}?
總結
以上是生活随笔為你收集整理的基于jwt的用户鉴权:拦截器概述的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 有状态服务和无状态服务的区别与联系
- 下一篇: 基于JWT的API权限校验:需求分析