当前位置: 首页 > news >正文

广州网站seo公司在网站上做漂浮

广州网站seo公司,在网站上做漂浮,网店美工是做什么的,天津津坤科技发展有限公司目录 1. 数据库设计 2. 代码设计 登录认证过滤器 认证成功处理器AuthenticationSuccessHandler 认证失败处理器AuthenticationFailureHandler AuthenticationEntryPoint配置 AccessDeniedHandler配置 UserDetailsService配置 Token校验过滤器 登录认证过滤器接口配置…目录 1. 数据库设计 2. 代码设计 登录认证过滤器 认证成功处理器AuthenticationSuccessHandler 认证失败处理器AuthenticationFailureHandler AuthenticationEntryPoint配置 AccessDeniedHandler配置 UserDetailsService配置 Token校验过滤器 登录认证过滤器接口配置 Spring Security全局配置 util包 测试结果 在SpringSecurity实现前后端分离登录token认证详解_springsecurity前后端分离登录认证-CSDN博客基础上进行重构实现前后端分离架构登录认证基本思想相同借鉴开源Gitee代码进行改造具有更好的代码规范。 1. 数据库设计 DROP TABLE IF EXISTS t_auth; CREATE TABLE t_auth (id BIGINT(11) NOT NULL AUTO_INCREMENT,name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 名称,url VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 路径,status INT(1) NULL DEFAULT NULL,create_time DATETIME(0) NULL DEFAULT NULL,update_time TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (id) USING BTREE ) ENGINE INNODB AUTO_INCREMENT 7 CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci ROW_FORMAT COMPACT;-- ---------------------------- -- Records of t_auth -- ---------------------------- INSERT INTO t_auth VALUES (1, 删除用户, /usr/del, 1, 2021-11-26 17:08:11, 2021-11-26 17:07:52); INSERT INTO t_auth VALUES (2, 新增用户, /usr/add, 1, 2021-11-26 17:08:13, 2021-11-26 17:08:09); INSERT INTO t_auth VALUES (3, 添加产品, /product/add, 1, 2021-11-26 17:08:42, 2021-11-26 17:08:29); INSERT INTO t_auth VALUES (4, 下架产品, /product/del, NULL, NULL, 2021-11-26 17:12:17); INSERT INTO t_auth VALUES (5, 注册, /user/register, NULL, NULL, 2021-11-26 17:13:32); INSERT INTO t_auth VALUES (6, 注销, /user/logOff, NULL, NULL, 2021-11-26 17:13:50);-- ---------------------------- -- Table structure for t_role -- ---------------------------- DROP TABLE IF EXISTS t_role; CREATE TABLE t_role (id BIGINT(11) NOT NULL,name VARCHAR(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 角色名称,status INT(1) NULL DEFAULT NULL,create_time DATETIME(0) NULL DEFAULT NULL,update_time TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (id) USING BTREE ) ENGINE INNODB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci ROW_FORMAT COMPACT;-- ---------------------------- -- Records of t_role -- ---------------------------- INSERT INTO t_role VALUES (1, ROLE_admin, 1, 2021-11-26 17:08:52, 2021-11-26 17:08:51); INSERT INTO t_role VALUES (2, ROLE_dba, 1, 2021-11-26 17:09:10, 2021-11-26 17:09:05); INSERT INTO t_role VALUES (3, ROLE_vip, 1, 2021-11-26 17:09:32, 2021-11-26 17:09:25); INSERT INTO t_role VALUES (4, ROLE_user, 1, 2021-11-26 17:09:45, 2021-11-26 17:09:42);-- ---------------------------- -- Table structure for t_role_auth -- ---------------------------- DROP TABLE IF EXISTS t_role_auth; CREATE TABLE t_role_auth (id BIGINT(20) NOT NULL AUTO_INCREMENT,role_id BIGINT(20) NULL DEFAULT NULL,auth_id BIGINT(20) NULL DEFAULT NULL,status INT(1) NULL DEFAULT NULL,create_time DATETIME(0) NULL DEFAULT NULL,update_time TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (id) USING BTREE ) ENGINE INNODB AUTO_INCREMENT 5 CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci ROW_FORMAT COMPACT;-- ---------------------------- -- Records of t_role_auth -- ---------------------------- INSERT INTO t_role_auth VALUES (1, 1, 3, 1, 2021-11-26 17:11:31, 2021-11-26 17:11:29); INSERT INTO t_role_auth VALUES (2, 1, 4, 1, 2021-11-26 17:11:31, 2021-11-26 17:11:29); INSERT INTO t_role_auth VALUES (3, 4, 5, 1, 2021-11-26 17:14:45, 2021-11-26 17:14:35); INSERT INTO t_role_auth VALUES (4, 4, 6, 1, 2021-11-26 17:14:47, 2021-11-26 17:14:41);-- ---------------------------- -- Table structure for t_user -- ---------------------------- DROP TABLE IF EXISTS t_user; CREATE TABLE t_user (id BIGINT(11) NOT NULL,user_id VARCHAR(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 唯一的userId,username VARCHAR(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 用户名,password VARCHAR(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 密码,name VARCHAR(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 姓名,status INT(1) NULL DEFAULT NULL,create_time DATETIME(0) NULL DEFAULT NULL,update_time TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (id) USING BTREE ) ENGINE INNODB CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci ROW_FORMAT COMPACT;-- ---------------------------- -- Records of t_user -- ---------------------------- INSERT INTO t_user VALUES (1, 120, zhangsan, 123456, 张三, 1, 2021-11-26 17:07:03, 2021-11-26 17:06:53); INSERT INTO t_user VALUES (2, 110, lisi, 123456, 李四, 1, 2021-11-26 17:07:36, 2021-11-26 17:07:12);-- ---------------------------- -- Table structure for t_user_role -- ---------------------------- DROP TABLE IF EXISTS t_user_role; CREATE TABLE t_user_role (id BIGINT(20) NOT NULL AUTO_INCREMENT,user_id VARCHAR(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 用户唯一userId,role_id BIGINT(20) NULL DEFAULT NULL,status INT(1) NULL DEFAULT NULL,create_time DATETIME(0) NULL DEFAULT NULL,update_time TIMESTAMP(0) NULL DEFAULT CURRENT_TIMESTAMP,PRIMARY KEY (id) USING BTREE ) ENGINE INNODB AUTO_INCREMENT 3 CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci ROW_FORMAT COMPACT;-- ---------------------------- -- Records of t_user_role -- ---------------------------- INSERT INTO t_user_role VALUES (1, 120, 1, 1, 2021-11-26 17:10:10, 2021-11-26 17:10:11); INSERT INTO t_user_role VALUES (2, 110, 2, 1, 2021-11-26 17:11:16, 2021-11-26 17:11:13); 2. 代码设计 登录认证过滤器 Spring Security默认的表单登录认证的过滤器是UsernamePasswordAuthenticationFilter这个过滤器并不适用于前后端分离的架构因此我们需要自定义一个过滤器。参照UsernamePasswordAuthenticationFilter这个过滤器改造一下。 /*** 登录认证的filter参照UsernamePasswordAuthenticationFilter添加到这之前的过滤器*/public class JwtAuthenticationLoginFilter extends AbstractAuthenticationProcessingFilter {/*** 构造方法调用父类的设置登录地址/login请求方式POST*/public JwtAuthenticationLoginFilter() {super(new AntPathRequestMatcher(/login, POST));}Overridepublic Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) {//获取表单提交数据String username request.getParameter(username);String password request.getParameter(password);//封装到token中提交UsernamePasswordAuthenticationToken authRequest new UsernamePasswordAuthenticationToken(username,password);return getAuthenticationManager().authenticate(authRequest);} } 认证成功处理器AuthenticationSuccessHandler 上述的过滤器接口一旦认证成功则会调用AuthenticationSuccessHandler进行处理因此我们可以自定义一个认证成功处理器进行自己的业务处理代码如下 Component public class LoginAuthenticationSuccessHandler implements AuthenticationSuccessHandler {Autowiredprivate JwtUtil jwtUtil;AutowiredRedisTemplate redisTemplate;Overridepublic void onAuthenticationSuccess(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse,Authentication authentication) throws IOException {UserDetails userDetails (UserDetails) authentication.getPrincipal();SecurityContextHolder.getContext().setAuthentication(authentication);MapString,String mapnew HashMap();map.put(username,userDetails.getUsername());//jwt生成tokenString token jwtUtil.getToken(map);RedisUser redisUser RedisUser.builder().username(userDetails.getUsername()).password(userDetails.getPassword()).authorities(userDetails.getAuthorities().stream().map(i-i.getAuthority()).collect(Collectors.toList())).build();//将用户信息保存到redis缓存中redisTemplate.opsForValue().set(userDetails.getUsername(),redisUser,12, TimeUnit.HOURS);ResponseUtils.result(httpServletResponse,new ResultMsg(200,登录成功,token));}} 认证失败处理器AuthenticationFailureHandler 同样的一旦登录失败比如用户名或者密码错误等等则会调用AuthenticationFailureHandler进行处理因此我们需要自定义一个认证失败的处理器其中根据异常信息返回特定的JSON数据给客户端代码如下 Component public class LoginAuthenticationFailureHandler implements AuthenticationFailureHandler {/*** 一旦登录失败则会被调用*/Overridepublic void onAuthenticationFailure(HttpServletRequest httpServletRequest,HttpServletResponse response,AuthenticationException exception) throws IOException {//TODO 根据项目需要返回指定异常提示,这里演示了一个用户名密码错误的异常//BadCredentialsException 这个异常一般是用户名或者密码错误if (exception instanceof BadCredentialsException){ResponseUtils.result(response,new ResultMsg(200,用户名或密码不正确,null));}ResponseUtils.result(response,new ResultMsg(200,登录失败,null));} } AuthenticationEntryPoint配置 AuthenticationEntryPoint这个接口当用户未通过认证访问受保护的资源时将会调用其中的commence()方法进行处理。 Component Slf4j public class EntryPointUnauthorizedHandler implements AuthenticationEntryPoint {Overridepublic void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {ResponseUtils.result(response,new ResultMsg(403,认证失败请重新登录,null));} } AccessDeniedHandler配置 AccessDeniedHandler这处理器当认证成功的用户访问受保护的资源但是权限不够则会进入这个处理器进行处理。 Component public class RequestAccessDeniedHandler implements AccessDeniedHandler {Overridepublic void handle(HttpServletRequest request,HttpServletResponse response,AccessDeniedException accessDeniedException) throws IOException {ResponseUtils.result(response,new ResultMsg(403,权限不足,null));} } UserDetailsService配置 UserDetailsService这个类是用来加载用户信息包括用户名、密码、权限、角色集合我们需要实现这个接口从数据库加载用户信息代码如下 Service public class JwtTokenUserDetailsService implements UserDetailsService {/*** 查询用户详情的service*/Autowiredprivate LoginService loginService;Overridepublic UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {//从数据库中查询SecurityUser securityUser loginService.loadByUsername(username);System.out.println(securityUser);//用户不存在直接抛出UsernameNotFoundExceptionsecurity会捕获抛出BadCredentialsExceptionif (Objects.isNull(securityUser))throw new UsernameNotFoundException(用户不存在);return securityUser;} } 其中的LoginService是根据用户名从数据库中查询出密码、角色、权限代码如下 Service public class LoginServiceImpl implements LoginService {Autowiredprivate PasswordEncoder passwordEncoder;AutowiredTUserService tUserService;AutowiredTRoleService tRoleService;NullableOverridepublic SecurityUser loadByUsername(String username) {//获取用户信息TUser user tUserService.getByUsername(username);if (Objects.nonNull(user)){SecurityUser securityUser new SecurityUser();securityUser.setUsername(username);//todo 此处为了方便直接在数据库存储的明文实际生产中应该存储密文则这里不用再次加密securityUser.setPassword(passwordEncoder.encode(user.getPassword()));//查询该用户的角色ListString userRoles tRoleService.selectAllByUsername(username);String[] a{};ListGrantedAuthority authorityList AuthorityUtils.createAuthorityList(userRoles.toArray(a));securityUser.setAuthorities(authorityList);return securityUser;}return null;}}UserDetails这个也是个接口其中定义了几种方法都是围绕着用户名、密码、权限角色集合这三个属性因此我们可以实现这个类拓展这些字段SecurityUser代码如下 Data public class SecurityUser implements UserDetails {//用户名private String username;//密码private String password;//权限private Collection? extends GrantedAuthority authorities;public SecurityUser(String username, String password, Collection? extends GrantedAuthority authorities) {this.username username;this.password password;this.authorities authorities;}public SecurityUser(){}Overridepublic Collection? extends GrantedAuthority getAuthorities() {return authorities;}Overridepublic String getPassword() {return password;}Overridepublic String getUsername() {return username;}// 账户是否未过期Overridepublic boolean isAccountNonExpired() {return true;}// 账户是否未被锁Overridepublic boolean isAccountNonLocked() {return true;}Overridepublic boolean isCredentialsNonExpired() {return true;}Overridepublic boolean isEnabled() {return true;} } Token校验过滤器 客户端请求头携带了token服务端肯定是需要针对每次请求解析、校验token因此必须定义一个Token过滤器这个过滤器的主要逻辑如下 从请求头中获取accessToken 对accessToken解析、验签、校验过期时间 校验成功将authentication存入ThreadLocal中这样方便后续直接获取用户详细信息。 Component public class TokenAuthenticationFilter extends OncePerRequestFilter {/*** JWT的工具类*/Autowiredprivate JwtUtil jwtUtil;/*** UserDetailsService的实现类从数据库中加载用户详细信息*/Qualifier(jwtTokenUserDetailsService)Autowiredprivate UserDetailsService userDetailsService;AutowiredRedisTemplate redisTemplate;Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {String token request.getHeader(token);/*** token存在则校验token* 1. token是否存在* 2. token存在* 2.1 校验token中的用户名是否失效*/if (!StringUtils.isEmpty(token)){DecodedJWT decodedJWT jwtUtil.getTokenInfo(token);String username;try {username decodedJWT.getClaim(username).asString();}catch (Exception e){throw new RuntimeException(token无效);}//从redis缓存中获得对应用户数据RedisUser redisUser (RedisUser) redisTemplate.opsForValue().get(username);String[] a{};ListGrantedAuthority authorityList AuthorityUtils.createAuthorityList(redisUser.getAuthorities().toArray(a));UsernamePasswordAuthenticationToken authentication new UsernamePasswordAuthenticationToken(redisUser, null,authorityList);authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));// 将 authentication 存入 ThreadLocal方便后续获取用户信息SecurityContextHolder.getContext().setAuthentication(authentication);}//继续执行下一个过滤器chain.doFilter(request,response);} } 登录认证过滤器接口配置 上述定义了一个认证过滤器JwtAuthenticationLoginFilter这个是用来登录的过滤器但是并没有注入加入Spring Security的过滤器链中需要定义配置代码如下 Configuration public class JwtAuthenticationSecurityConfig extends SecurityConfigurerAdapterDefaultSecurityFilterChain, HttpSecurity {/*** userDetailService*/Qualifier(jwtTokenUserDetailsService)Autowiredprivate UserDetailsService userDetailsService;/*** 登录成功处理器*/Autowiredprivate LoginAuthenticationSuccessHandler loginAuthenticationSuccessHandler;/*** 登录失败处理器*/Autowiredprivate LoginAuthenticationFailureHandler loginAuthenticationFailureHandler;/*** 加密*/Autowiredprivate PasswordEncoder passwordEncoder;/*** 将登录接口的过滤器配置到过滤器链中* 1. 配置登录成功、失败处理器* 2. 配置自定义的userDetailService从数据库中获取用户数据* 3. 将自定义的过滤器配置到spring security的过滤器链中配置在UsernamePasswordAuthenticationFilter之前* param*/Overridepublic void configure(HttpSecurity http) {JwtAuthenticationLoginFilter filter new JwtAuthenticationLoginFilter();filter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class));//认证成功处理器filter.setAuthenticationSuccessHandler(loginAuthenticationSuccessHandler);//认证失败处理器filter.setAuthenticationFailureHandler(loginAuthenticationFailureHandler);//直接使用DaoAuthenticationProviderDaoAuthenticationProvider provider new DaoAuthenticationProvider();//设置userDetailServiceprovider.setUserDetailsService(userDetailsService);//设置加密算法provider.setPasswordEncoder(passwordEncoder);http.authenticationProvider(provider);//将这个过滤器添加到UsernamePasswordAuthenticationFilter之前执行http.addFilterBefore(filter, UsernamePasswordAuthenticationFilter.class);} } Spring Security全局配置 上述仅仅配置了登录过滤器还需要在全局配置类做一些配置如下 应用登录过滤器的配置 将登录接口、令牌刷新接口放行不需要拦截 配置AuthenticationEntryPoint、AccessDeniedHandler 禁用session前后端分离JWT方式不需要session 将token校验过滤器TokenAuthenticationFilter添加到过滤器链中放在UsernamePasswordAuthenticationFilter之前。 Configuration //EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter {Autowiredprivate JwtAuthenticationSecurityConfig jwtAuthenticationSecurityConfig;Autowiredprivate EntryPointUnauthorizedHandler entryPointUnauthorizedHandler;Autowiredprivate RequestAccessDeniedHandler requestAccessDeniedHandler;Overrideprotected void configure(HttpSecurity http) throws Exception {http.formLogin()//禁用表单登录前后端分离用不上.disable()//应用登录过滤器的配置配置分离.apply(jwtAuthenticationSecurityConfig).and()// 设置URL的授权.authorizeRequests().antMatchers(/login).permitAll()// anyRequest() 所有请求 authenticated() 必须被认证.anyRequest().authenticated()//处理异常情况认证失败和权限不足.and().exceptionHandling()//认证未通过不允许访问异常处理器.authenticationEntryPoint(entryPointUnauthorizedHandler)//认证通过但是没权限处理器.accessDeniedHandler(requestAccessDeniedHandler).and()//禁用sessionJWT校验不需要session.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()//将TOKEN校验过滤器配置到过滤器链中否则不生效放到UsernamePasswordAuthenticationFilter之前.addFilterBefore(authenticationTokenFilterBean(), UsernamePasswordAuthenticationFilter.class)// 关闭csrf.csrf().disable();}// 自定义的Jwt Token校验过滤器Beanpublic TokenAuthenticationFilter authenticationTokenFilterBean() {return new TokenAuthenticationFilter();}/*** 加密算法** return*/BeanOverrideprotected AuthenticationManager authenticationManager() throws Exception {return super.authenticationManager();} } util包 JWT工具类 Component ConfigurationProperties(prefix jwt) //Data public class JwtUtil {private String signaturecbac;private Integer expiration12;/**** 生成token header.payload.signature*/public String getToken(MapString,String payload){Calendar calendar Calendar.getInstance();calendar.add(Calendar.HOUR, 24); // 24小时JWTCreator.Builder builder JWT.create();// 构建payloadpayload.forEach(builder::withClaim);// 指定签发时间、过期时间 和 签名算法并返回tokenString token builder.withIssuedAt(new Date()).withExpiresAt(calendar.getTime()).sign(Algorithm.HMAC256(signature));return token;}/**** 获取token信息*/public DecodedJWT getTokenInfo(String token){DecodedJWT verifyJWT.require(Algorithm.HMAC256(signature)).build().verify(token);return verify;}} 结果封装类 public class ResponseUtils {public static void result(HttpServletResponse response, ResultMsg msg) throws IOException {response.setContentType(application/json;charsetUTF-8);ServletOutputStream out response.getOutputStream();ObjectMapper objectMapper new ObjectMapper();out.write(objectMapper.writeValueAsString(msg).getBytes(UTF-8));out.flush();out.close();} }测试结果 项目目录结构
http://www.w-s-a.com/news/966938/

相关文章:

  • 秦皇岛网站建设服务聊城做网站的公司资讯
  • 30岁转行做网站设计丰涵网站建设
  • 山东省和住房建设厅网站首页开发商不按时交房可以退房吗
  • asp网站怎么做404页面跳转本地南通网站建设
  • 点击网站出现微信二维码的链接怎么做申请网站空间怎么做
  • 网站开发的论文题目广告设计排行榜
  • 网络营销网站 功能南京h5制作公司
  • 做网站的费用的会计分录合肥做网站推广哪家好
  • 电子商城网站开发怎么wordpress用的什么主题
  • 榆林电商网站建设网上做试卷的网站
  • 文山网站建设代理中公教育培训机构官网
  • 郑州it培训机构有哪些上海外贸网站seo
  • dw做网站的实用特效广东住房与城乡建设厅网站
  • 模板网站 动易哪方面的网站
  • 怎么给网站做外链邵连虎郑州做网页的公司
  • 重庆网站开发哪家好宁波网站建设caiyiduo
  • 手机网站建设价格手机网站模版更换技巧
  • 哈尔滨松北区建设局网站美妆网站建设
  • 不需要网站备案的空间网站推广的基本方法是哪四个
  • 如何检查网站死链劳动仲裁院内部网站建设
  • 江西省住房和城乡建设网站合同管理系统
  • 网站建设质量保证福州网络推广
  • 高唐网站建设公司广州南站在哪个区
  • 广西柳州网站制作公司郴州网红打卡景点
  • 做网站要固定ip拍摄公司宣传片制作
  • 专业微网站电话号码做软件难吗
  • 邢台网站制作哪家强上海做网站设计
  • 大连网站建设外贸wordpress添加文章属性
  • 商城网站建设合同范本网上哪里可以免费学编程
  • 服务器公司网站博客wordpress怎么编辑