从0到1搭建前后端分离的脚手架框架之后端(六) 鉴权
2020-01-14 16:33
162 查看
鉴权
通过jwt做授权认证操作,
AuthorizationInterceptor拦截器来判断token的合法性,包括是否登录,是否有权限访问某个资源,由于跨域问题,所以
OPTIONS请求将直接跳过,不进行校验,
WebAppConfig进行拦截器注册和跨域设置 代码如下:
public class AuthorizationInterceptor implements HandlerInterceptor { private static final String METHOD_OPTIONS = "OPTIONS"; private final PermissionService permissionService; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 跨域时两段验证,当请求方法为OPTIONS直接跳过,不用判断是否登录 if (Objects.equals(METHOD_OPTIONS, request.getMethod())) { return true; } String token = JwtTokenHelper.findTokenByRequest(); if (StringUtils.isBlank(token) || JwtTokenHelper.verify(token)) { authFailure(response, HttpServletResponse.SC_UNAUTHORIZED, AuthCode.NOT_LOGIN); return false; } Pair<String, String> pair = JwtTokenHelper.parseToken(token); AuthToken authToken = UserContextHelper.getCurrentUser(); boolean isVerify = !Objects.isNull(authToken) && !Objects.isNull(pair) && Objects.equals(pair.getLeft(), authToken.getUserId()) && Objects.equals(pair.getRight(), authToken.getUsername()) && Objects.equals(authToken.getLoginIp(), WebUtils.getIpAddress()); if (!isVerify) { authFailure(response, HttpServletResponse.SC_UNAUTHORIZED, AuthCode.NOT_LOGIN); return false; } UserInfoDTO userInfo = (UserInfoDTO) authToken; if (!permissionService.hasPermission(request.getRequestURI(), userInfo)) { authFailure(response, HttpServletResponse.SC_FORBIDDEN, AuthCode.FORBIDDEN); return false; } return true; } private void authFailure(HttpServletResponse response, int responseCode, RestCode code) throws IOException { log.warn("token验证失败 token -> {}, ip -> {}, url -> {}", JwtTokenHelper.findTokenByRequest(), WebUtils.getIpAddress(), WebUtils.getRequest().getRequestURI()); response.setContentType("application/json;charset=UTF-8"); response.setHeader("Cache-Control", "no-cache"); response.setHeader("Access-Control-Allow-Origin", "*"); response.setStatus(responseCode); response.getWriter().write(JSON.toJSONString(RestResponse.error(code))); } }
@Configuration @AllArgsConstructor public class WebAppConfig implements WebMvcConfigurer { private final AuthorizationInterceptor authorizationInterceptor; private final ApplicationConfig.AuthConfig authConfig; @Override public void addInterceptors(InterceptorRegistry registry) { // 认证拦截器 registry.addInterceptor(authorizationInterceptor) .excludePathPatterns(authConfig.getAuthenticateExcludeUrl()) .addPathPatterns("/**"); } @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowedOrigins(CorsConfiguration.ALL) .allowedHeaders(CorsConfiguration.ALL) .allowedMethods(CorsConfiguration.ALL) .allowCredentials(true) .exposedHeaders("Header1", "Header2"); } }
auth: authenticate-exclude-url: - /auth/login - /error
token发放通过登录操作完成:
@RestController @AllArgsConstructor @RequestMapping("/auth") public class AuthController { private final AuthService authService; /** * <p>Title: login * <p>Description: 登录 * * @param user 用户 * * @return com.yousuf.platform.common.core.RestResponse<java.lang.String> * * @author zhangshuai 2019/11/8 * */ @PostMapping("/login") public RestResponse<String> login(@RequestBody @Valid UserInfoDTO user) { UserInfoDTO currentUser = authService.login(user); if (Objects.isNull(currentUser)) { return RestResponse.error(AuthCode.USER_PASSWORD_ERROR); } // 生成token String token = JwtTokenHelper.generateToken(currentUser.getUserId(), currentUser.getUsername()); UserContextHelper.setCurrentUser(token, currentUser); return RestResponse.success(token); } /** * <p> Title: findUserInfo * <p> Description: 获取当前用户信息 * * @return com.yousuf.platform.common.core.RestResponse<com.yousuf.platform.vo.UserInfoDTO> * @author yousuf zhang 2019/11/8 **/ @GetMapping("/info") public RestResponse<UserInfoDTO> findUserInfo() { UserInfoDTO userInfo = (UserInfoDTO) UserContextHelper.getCurrentUser(); return RestResponse.success(userInfo); } /** * <p>Title: logout * <p>Description: 退出 * * @return com.yousuf.platform.common.core.RestResponse<java.lang.Void> * * @author yousuf zhang 2019/11/8 **/ @GetMapping("/logout") public RestResponse<Void> logout() { UserContextHelper.removeCurrentUser(); return RestResponse.success(); } }
- 点赞
- 收藏
- 分享
- 文章举报
相关文章推荐
- 从0到1搭建前后端分离的脚手架框架之后端(七)JPA整合
- 搭建spring-boot+vue前后端分离框架并实现登录功能
- 从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之八MemoryCache与redis缓存的使用
- 从MVC到前后端分离(Rest框架搭建)
- 从壹开始前后端分离【 .NET Core2.0 Api + Vue 2.0 + AOP + 分布式】框架之七 || API项目整体搭建 6.2 轻量级ORM
- 从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之二autofac解耦
- Vue .Net 前后端分离框架搭建
- 从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之十一Swagger使用一
- Maven多模块,Dubbo分布式服务框架,SpringMVC,前后端分离项目,基础搭建,搭建过程出
- 从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之八MemoryCache与redis缓存的使用...
- 从MVC到前后端分离(Rest框架搭建)
- 前后端分离-vue基础开发框架搭建
- 从壹开始前后端分离【 .NET Core2.0 Api + Vue 2.0 + AOP + 分布式】框架之二 || 后端项目搭建
- 从壹开始前后端分离【 .NET Core2.0 Api + Vue 2.0 + AOP + 分布式】框架之八 || API项目整体搭建 6.3 异步泛型+依赖注入初探
- Maven多模块,Dubbo分布式服务框架,SpringMVC,前后端分离项目,基础搭建,搭建过程出现的问题
- BLUENESSG 早一日受苦、早一日解决、早一日浴火重生 Maven多模块,Dubbo分布式服务框架,SpringMVC,前后端分离项目,基础搭建,搭建过程出现的问题
- 从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之九如何进行用户权限控制
- 从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之四Nlog记录日志至数据库
- 从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之二autofac解耦...
- 从零开始搭建前后端分离的NetCore2.2(EF Core CodeFirst+Autofac)+Vue的项目框架之十二Swagger(参数)使用二