当前位置:   article > 正文

SpringSecurity+SpringSecurityOauth2集成实现权限框架,Redis分发Token_org.springframework.security.oauth2.provider.token

org.springframework.security.oauth2.provider.token.store.redis.redistokensto

       写在前面:当我们开始使用Security的时候,常常因为各种注入,而迷糊,但是很害怕使用security,感觉很重很难用!再加入oauth2更难搞,今天我就写点自己的配置理解,希望对大家有帮助!(会提供一个可以使用的源码,放在最后,如果你不想看内容,可以直接下载!)

一: spring security 的核心功能主要包括:

  • 认证 (你是谁)
  • 授权 (你能干什么)
  • 攻击防护 (防止伪造身份)

        oauth2根据使用场景不同,分成了4种模式,感兴趣的可以去了解,我们主要用密码模式,说白了就是账号密码登录模式

我们主要用认证 ——授权 ——发放Token

二:直接开始

1.核心依赖(主要就是这两个,其他的随便导下就行了,reids,mysql的自己弄下)

  1. <!--security依赖-->
  2. <dependency>
  3. <groupId>org.springframework.boot</groupId>
  4. <artifactId>spring-boot-starter-security</artifactId>
  5. </dependency>
  6. <!--oauth2依赖-->
  7. <dependency>
  8. <groupId>org.springframework.security.oauth</groupId>
  9. <artifactId>spring-security-oauth2</artifactId>
  10. <version>2.3.3.RELEASE</version>
  11. </dependency>

2.Yml配置文件(为了节省空间,其他配置不放了,redis,mysql的大家自己根据自己情况使用)

  1. # oauth2.0配置
  2. client:
  3. oauth2:
  4. client-id: appId # 客户端标识Id
  5. secret: 123456 # 客户端安全码
  6. # 授权类型
  7. grant_types:
  8. - password
  9. - refresh_token
  10. # token 有效期
  11. token-validity-time: 3600
  12. refresh-token-validity-time: 3600
  13. # 客户端访问范围
  14. scopes:
  15. - api
  16. - all

3.下面就开始核心代码编写了

第一就是security的配置类,该类相当核心,主要注入几个核心功能,先贴代码

  1. package io.springboot.netty.oauth2server;
  2. import org.apache.commons.codec.digest.DigestUtils;
  3. import org.springframework.context.annotation.Bean;
  4. import org.springframework.context.annotation.Configuration;
  5. import org.springframework.data.redis.connection.RedisConnectionFactory;
  6. import org.springframework.security.authentication.AuthenticationManager;
  7. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  8. import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
  9. import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
  10. import org.springframework.security.crypto.password.PasswordEncoder;
  11. import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
  12. import javax.annotation.Resource;
  13. /**
  14. * Security 配置类
  15. *
  16. * @author zheng
  17. */
  18. @Configuration
  19. @EnableWebSecurity
  20. public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
  21. /**
  22. * 注入redis 连接工厂
  23. */
  24. @Resource
  25. private RedisConnectionFactory redisConnectionFactory;
  26. /**
  27. * 初始化 redisTokenStore 用户将token 放入redis
  28. * @return
  29. */
  30. @Bean
  31. public RedisTokenStore redisTokenStore(){
  32. RedisTokenStore redisTokenStore = new RedisTokenStore(redisConnectionFactory);
  33. redisTokenStore.setPrefix("TOKEN:");
  34. return redisTokenStore;
  35. }
  36. /**
  37. * 初始化密码编码器 MD5加密
  38. * @return
  39. */
  40. @Bean
  41. public PasswordEncoder passwordEncoder(){
  42. return new PasswordEncoder() {
  43. /**
  44. * 加密
  45. * @param rawPassword 原始密码
  46. * @return
  47. */
  48. @Override
  49. public String encode(CharSequence rawPassword) {
  50. return DigestUtils.md5Hex(rawPassword.toString());
  51. }
  52. /**
  53. * 校验密码
  54. * @param rawPassword 原始密码
  55. * @param encoderPassword 加密后密码
  56. * @return
  57. */
  58. @Override
  59. public boolean matches(CharSequence rawPassword, String encoderPassword) {
  60. return DigestUtils.md5Hex(rawPassword.toString()).equals(encoderPassword);
  61. }
  62. };
  63. }
  64. /**
  65. * 初始化管理对象
  66. */
  67. @Override
  68. @Bean
  69. public AuthenticationManager authenticationManager() throws Exception {
  70. return super.authenticationManager();
  71. }
  72. /**
  73. * 放行 和 认证规则
  74. * @param http
  75. * @throws Exception
  76. */
  77. @Override
  78. protected void configure(HttpSecurity http) throws Exception {
  79. http.csrf().disable()
  80. .authorizeRequests()
  81. // 放行
  82. .antMatchers("/oauth/**", "/actuator/**")
  83. .permitAll()
  84. .and()
  85. .authorizeRequests()
  86. .anyRequest()
  87. // 其他需要拦截
  88. .authenticated();
  89. }
  90. }

        1.RedisConnectionFactory 注入redis的连接工厂,

        2.初始化 redisTokenStore 用户将token 放入redis,也可以放入内存当中,建议放入redis中。

        3.初始化密码编码器,使用MD5,亦可以换成security的加密方式。重写加密方法-encode,修改加密方式,重写校验方法-matches.

        4.初始化 AuthenticationManager认证管理对象

        5.重写config方法,配置放行和认证 、/oauth 等会我们重写它,做为登录方法使用

        "/oauth/**", "/actuator/**"

这个方法还是比较简单的,主要为了注入bean和配置一个拦截方法

授权配置类
  1. import io.springboot.netty.entity.LoginUser;
  2. import io.springboot.netty.service.impl.UserServiceImpl;
  3. import org.springframework.beans.factory.annotation.Autowired;
  4. import org.springframework.context.annotation.Configuration;
  5. import org.springframework.security.authentication.AuthenticationManager;
  6. import org.springframework.security.crypto.password.PasswordEncoder;
  7. import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
  8. import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
  9. import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
  10. import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
  11. import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
  12. import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
  13. import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
  14. import javax.annotation.Resource;
  15. import java.util.LinkedHashMap;
  16. /**
  17. * 授权配置类
  18. * @author zheng
  19. */
  20. @Configuration
  21. @EnableAuthorizationServer
  22. public class AuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
  23. @Autowired
  24. private UserServiceImpl userService;
  25. @Resource
  26. private RedisTokenStore redisTokenStore;
  27. /**
  28. * 管理器
  29. */
  30. @Resource
  31. private AuthenticationManager authenticationManager;
  32. /**
  33. * 密码编码器
  34. */
  35. @Resource
  36. private PasswordEncoder passwordEncoder;
  37. /**
  38. * 客户端配置类
  39. */
  40. @Resource
  41. private ClientOauth2DataConfiguration oauth2DataConfiguration;
  42. /**
  43. * 客户端配置授权模型
  44. * @param clients
  45. * @throws Exception
  46. */
  47. @Override
  48. public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
  49. clients.inMemory().withClient(oauth2DataConfiguration.getClientId())
  50. .secret(passwordEncoder.encode(oauth2DataConfiguration.getSecret()))
  51. .authorizedGrantTypes(oauth2DataConfiguration.getGrantTypes()) // token 授权类型
  52. .accessTokenValiditySeconds(oauth2DataConfiguration.getTokenValidityTime()) // token 过期时间
  53. .refreshTokenValiditySeconds(oauth2DataConfiguration.getRefreshTokenValidityTime()) // token 刷新过期时间
  54. .scopes(oauth2DataConfiguration.getScopes());
  55. }
  56. /**
  57. * 配置令牌端点的安全约束
  58. * @param security
  59. * @throws Exception
  60. */
  61. @Override
  62. public void configure(AuthorizationServerSecurityConfigurer security) throws Exception {
  63. // 允许访问 token 的公钥,默认 /oauth/token_key 受保护的
  64. security.tokenKeyAccess("permitAll()")
  65. // 允许访问 token 的状态,默认 /oauth/check_token 受保护的
  66. .checkTokenAccess("permitAll()");
  67. }
  68. @Override
  69. public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
  70. // 认证器
  71. endpoints.authenticationManager(authenticationManager)
  72. // 具体登陆方法
  73. .userDetailsService(userService)
  74. // token 存储方式 redis
  75. .tokenStore(redisTokenStore)
  76. // 令牌增强对象 , 增强返回的结果
  77. .tokenEnhancer((accessToken, authentication) ->{
  78. // 获取用户信息,然后设置
  79. LoginUser loginUser = (LoginUser) authentication.getPrincipal();
  80. LinkedHashMap<String, Object> map = new LinkedHashMap<>();
  81. map.put("userId",loginUser.getUserId());
  82. map.put("usernmae",loginUser.getUsername());
  83. map.put("logo", loginUser.getLogo());
  84. DefaultOAuth2AccessToken token = (DefaultOAuth2AccessToken) accessToken;
  85. token.setAdditionalInformation(map);
  86. return token;
  87. });
  88. }
  89. }

这个方法中,我们可以看到上一个方法注入的几个bean,并且重写三个配置类1.config,configure(ClientDetailsServiceConfigurer clients),客户端配置授权模型,就是我们所说oauth2的四个模式,我们就用一个密码模式。

2.configure(AuthorizationServerSecurityConfigurer security),配置令牌端点的安全约束,上面我们也提到了重写/oauth/**接口来实现登录,在这里要先给它放行,否则我们都请求不到!

3.configure(AuthorizationServerEndpointsConfigurer endpoints),这里就是配置认证器了,我们先将管理器注入(authenticationManager),然后实现具体登录方法,主要就是为了登录校验密码,然后设置token的存放方式,最后对令牌做一个增强,就是要返回那些信息。

UserServiceImpl和ClientOauth2DataConfiguration,我们不知道是干嘛的,其实userServiceImpl不说都很清楚,就是为了校验登录用的,后面这个是为了加载client.ouath2的yml数据的,数据在上面的YML文件中
  1. import lombok.Data;
  2. import org.springframework.boot.context.properties.ConfigurationProperties;
  3. import org.springframework.stereotype.Component;
  4. /**
  5. * 客户端数据配置类
  6. * @author zheng
  7. */
  8. @Component
  9. @ConfigurationProperties(prefix = "client.oauth2")
  10. @Data
  11. public class ClientOauth2DataConfiguration {
  12. private String clientId;
  13. private String secret;
  14. private String[] grantTypes;
  15. private int tokenValidityTime;
  16. private int refreshTokenValidityTime;
  17. private String[] scopes;
  18. }

UserServiceImpl 实现UserDetailes.类,重写了loadUserName方法

  1. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  2. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  3. import org.springframework.beans.BeanUtils;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.security.core.userdetails.UserDetails;
  6. import org.springframework.security.core.userdetails.UserDetailsService;
  7. import org.springframework.security.core.userdetails.UsernameNotFoundException;
  8. import security.oauth2.entity.LoginUser;
  9. import security.oauth2.entity.ManorUser;
  10. import security.oauth2.mapper.ManorUserMapper;
  11. public class UserServiceImpl extends ServiceImpl<ManorUserMapper, ManorUser> implements UserService, UserDetailsService {
  12. @Autowired
  13. private ManorUserMapper userMapper;
  14. /**
  15. * Security 用户登陆实现方法
  16. * @param username
  17. * @return
  18. * @throws UsernameNotFoundException
  19. */
  20. @Override
  21. public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
  22. ManorUser user = userMapper.selectOne(new LambdaQueryWrapper<ManorUser>().eq(ManorUser::getUserId, username));
  23. LoginUser loginUser = new LoginUser();
  24. // 复制用户信息
  25. BeanUtils.copyProperties(user,loginUser);
  26. // return new User(username,user.getPassword(), AuthorityUtils.commaSeparatedStringToAuthorityList(null));
  27. return loginUser;
  28. }
  29. }
ManorUser是数据库表中用户表的实体类,LoginUser需要实现UserDetails中的几个方法
  1. import org.springframework.security.core.userdetails.UserDetails;
  2. import com.baomidou.mybatisplus.annotation.TableId;
  3. import com.google.common.collect.Lists;
  4. import lombok.Getter;
  5. import lombok.Setter;
  6. import org.apache.commons.lang3.StringUtils;
  7. import org.springframework.security.core.GrantedAuthority;
  8. import org.springframework.security.core.authority.AuthorityUtils;
  9. import org.springframework.security.core.authority.SimpleGrantedAuthority;
  10. import java.util.Collection;
  11. import java.util.Date;
  12. import java.util.List;
  13. import java.util.stream.Collectors;
  14. import java.util.stream.Stream;
  15. /**
  16. * @author zheng
  17. */
  18. @Getter
  19. @Setter
  20. public class LoginUser implements UserDetails {
  21. /**
  22. *
  23. */
  24. @TableId
  25. private Integer id;
  26. /**
  27. * 是否需要引导(默认为0,需要 1:不需要)
  28. */
  29. private Integer guideType;
  30. /**
  31. * 等级
  32. */
  33. private Integer level;
  34. /**
  35. * 用户经验值
  36. */
  37. private Integer experience;
  38. /**
  39. * 种植水果类型 (默认0:未种 1.桃树,2.梨树,3.西瓜,4.草莓,5.葡萄)
  40. */
  41. private Integer fruitsType;
  42. /**
  43. * 果树等级
  44. */
  45. private Integer fruitsLevel;
  46. /**
  47. * 果树经验值
  48. */
  49. private Integer fruitsExp;
  50. /**
  51. * 用户id
  52. */
  53. private Integer userId;
  54. /**
  55. * 弹幕开启:0 关闭 1:开启
  56. */
  57. private Integer setBulletArr;
  58. private Date createTime;
  59. private Integer state;
  60. /**
  61. * 肥料
  62. */
  63. private Integer manureNum;
  64. /**
  65. * 水
  66. */
  67. private Integer waterNum;
  68. /**
  69. * 加速卡
  70. */
  71. private Integer cardNum;
  72. /**
  73. * 当月前用户签到总数
  74. */
  75. private Integer addSign;
  76. private String logo;
  77. private String username;
  78. private String password;
  79. private String roles;
  80. private List<GrantedAuthority> authorities;
  81. //** 获取角色信息
  82. @Override
  83. public Collection<? extends GrantedAuthority> getAuthorities() {
  84. if (StringUtils.isNotBlank(this.roles)){
  85. //获取数据库中角色
  86. Lists.newArrayList();
  87. this.authorities = Stream.of(this.roles.split(",")).map(role ->{
  88. return new SimpleGrantedAuthority(role);
  89. }).collect(Collectors.toList());
  90. }else{
  91. // 如果角色为空
  92. this.authorities = AuthorityUtils
  93. .commaSeparatedStringToAuthorityList("ROLE_USER");
  94. }
  95. return this.authorities;
  96. }
  97. @Override
  98. public String getPassword() {
  99. return this.password;
  100. }
  101. @Override
  102. public String getUsername() {
  103. return this.username;
  104. }
  105. @Override
  106. public boolean isAccountNonExpired() {
  107. return true;
  108. }
  109. @Override
  110. public boolean isAccountNonLocked() {
  111. return true;
  112. }
  113. @Override
  114. public boolean isCredentialsNonExpired() {
  115. return true;
  116. }
  117. @Override
  118. public boolean isEnabled() {
  119. return this.state == 0 ? false : true;
  120. }
  121. }

配置完成上面这些东西,我们就可以获取了TOKEN了,我们来重写一个登录方法,写一个验证接口

  1. package security.oauth2.controller;
  2. import lombok.SneakyThrows;
  3. import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
  4. import org.springframework.security.oauth2.common.OAuth2AccessToken;
  5. import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
  6. import org.springframework.web.HttpRequestMethodNotSupportedException;
  7. import org.springframework.web.bind.annotation.PostMapping;
  8. import org.springframework.web.bind.annotation.RequestMapping;
  9. import org.springframework.web.bind.annotation.RequestParam;
  10. import org.springframework.web.bind.annotation.RestController;
  11. import javax.annotation.Resource;
  12. import java.security.Principal;
  13. import java.util.LinkedHashMap;
  14. import java.util.Map;
  15. /**
  16. * @author zheng
  17. */
  18. @RestController
  19. @RequestMapping("oauth")
  20. public class OauthController {
  21. /**
  22. * 返回增强
  23. */
  24. @Resource
  25. private TokenEndpoint tokenEndpoint;
  26. @PostMapping("token")
  27. public Map<String, Object> postAccessToken(Principal principal, @RequestParam Map<String,String> param) throws HttpRequestMethodNotSupportedException {
  28. Map<String, Object> map = custom(tokenEndpoint.postAccessToken(principal, param).getBody());
  29. return map;
  30. }
  31. private Map<String,Object> custom(OAuth2AccessToken oAuth2AccessToken){
  32. DefaultOAuth2AccessToken token = (DefaultOAuth2AccessToken) oAuth2AccessToken;
  33. Map<String,Object> data = new LinkedHashMap(token.getAdditionalInformation());
  34. data.put("accessToken",token.getValue());
  35. data.put("expireIn", token.getExpiresIn());
  36. data.put("scopes", token.getScope());
  37. if (token.getRefreshToken() != null){
  38. data.put("refreshToken",token.getRefreshToken().getValue());
  39. }
  40. return data;
  41. }
  42. }

感兴趣的朋友可以去查查看令牌增强的用处,其实就是返回Token的使用,可以带点你自定义的信息给页面仔用。

我们来使用来测试下,我用的APIpost,你也可以用其他的测试工具

 图上可以看下参数,账号密码,没什么说的,grant_type = password,就是我上面提到的密码模式,scope,指的是接口可访问的范围,这两个参数在YML文件中,都配置了,在请求的时需要传递,在Body旁边,有个认证,postman中为英文认证单词,点击进入

 这两个参数需要从yml读取,也就是client-id和secret的值,我这里选择配置文件加载,主要就是为了验证前后端是否有资格使用登录接口,如果配置的值不一致,也是请求不了接口的。还有一种方式是从数据库中加载,security也提供了相应的方式,更加灵活点。

  1. {
  2. "userId": 10148629,
  3. "usernmae": "抽奖专用小马甲",
  4. "logo": "http://logo.sqsjt.net/upfiles/user/face/90/9005c1be3839c52c52c97e7589e46d5c.jpg?5F1FF05C",
  5. "accessToken": "5bb9602b-89bb-42d6-a4b6-3d35db9bea2a",
  6. "expireIn": 2489,
  7. "scopes": [
  8. "api"
  9. ],
  10. "refreshToken": "0979b94e-3f85-4e5b-afa2-719f0ae17bb2"
  11. }

请求成功后,就是返回了这些,从参数可以看到我们实现的令牌增强功能,返回了自定义的三个参数,userId,username,logo,可以配置更多参数,剩下的token参数则是在 OauthController.custom中配置了。

请求成功后,我们可以在redis中看到Token的相关信息,如下图

        可是我们用token去请求接口的时候,还是会提示403,找不到相关资源,这个是因为我们还没有配置资源配置类

  1. package security.oauth2.oauth2Server;
  2. import org.springframework.context.annotation.Configuration;
  3. import org.springframework.security.config.annotation.web.builders.HttpSecurity;
  4. import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
  5. import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
  6. import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
  7. import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
  8. import javax.annotation.Resource;
  9. /**
  10. * @author zheng
  11. */
  12. @Configuration
  13. @EnableResourceServer
  14. public class ResourceServerConfig extends ResourceServerConfigurerAdapter {
  15. @Resource
  16. private MyAuthenticationEntryPoint myAuthenticationEntryPoint;
  17. @Resource
  18. private RedisTokenStore redisTokenStore;
  19. @Override
  20. public void configure(HttpSecurity http) throws Exception {
  21. http.authorizeRequests().anyRequest()
  22. .authenticated()
  23. .and()
  24. .requestMatchers().antMatchers("/user/**");
  25. }
  26. @Override
  27. public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
  28. // 设置token存储
  29. resources.tokenStore(redisTokenStore);
  30. // 设置验证失败
  31. resources.authenticationEntryPoint(myAuthenticationEntryPoint);
  32. }
  33. }

重写config方法,验证/user/**开头的请求接口,这里可以根据具体业务配置,我们写一个UserController,来查询下用户的基本信息。

  1. package security.oauth2.controller;
  2. import org.springframework.security.core.Authentication;
  3. import org.springframework.web.bind.annotation.GetMapping;
  4. import org.springframework.web.bind.annotation.RestController;
  5. /**
  6. * 用户中心
  7. * @author zheng
  8. */
  9. @RestController
  10. public class UserController {
  11. @GetMapping("user/me")
  12. public Object postAccessToken(Authentication authentication){
  13. Object principal = authentication.getPrincipal();
  14. return principal;
  15. }
  16. }

直接请求接口,使用/oauth/token返回的access_token,可以看出来,返回了用户基本信息

用户表结构

  1. /*
  2. Navicat Premium Data Transfer
  3. Source Server : localhost
  4. Source Server Type : MySQL
  5. Source Server Version : 50725
  6. Source Host : localhost:3306
  7. Source Schema : yami_shops
  8. Target Server Type : MySQL
  9. Target Server Version : 50725
  10. File Encoding : 65001
  11. Date: 24/08/2021 00:33:39
  12. */
  13. SET NAMES utf8mb4;
  14. SET FOREIGN_KEY_CHECKS = 0;
  15. -- ----------------------------
  16. -- Table structure for manor_user
  17. -- ----------------------------
  18. DROP TABLE IF EXISTS `manor_user`;
  19. CREATE TABLE `manor_user` (
  20. `id` int(11) NOT NULL AUTO_INCREMENT,
  21. `guide_type` tinyint(1) DEFAULT 0 COMMENT '是否需要引导(默认为0,需要 1:不需要)',
  22. `level` int(255) DEFAULT 1 COMMENT '用户等级',
  23. `experience` int(255) DEFAULT 0 COMMENT '用户经验值',
  24. `fruits_type` tinyint(1) DEFAULT 0 COMMENT '种植水果类型 (默认0:未种 1.桃树,2.梨树,3.西瓜,4.草莓,5.葡萄)',
  25. `fruits_exp` int(255) DEFAULT 0 COMMENT '果树经验值',
  26. `user_id` int(20) NOT NULL COMMENT '用户id',
  27. `fruits_level` tinyint(2) DEFAULT 0 COMMENT '果树等级',
  28. `set_bullet_arr` tinyint(1) DEFAULT 1 COMMENT '弹幕开启:0 关闭 1:开启',
  29. `create_time` datetime(0) DEFAULT NULL COMMENT '创建时间',
  30. `state` tinyint(1) DEFAULT 1 COMMENT '状态:1 启用 0 禁用',
  31. `manure_num` int(11) DEFAULT 0 COMMENT '肥料',
  32. `water_num` int(11) DEFAULT 0 COMMENT '水',
  33. `card_num` int(11) DEFAULT NULL COMMENT '加速卡',
  34. `add_sign` int(255) DEFAULT 0 COMMENT '本月前用户签到总数',
  35. `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '用户名',
  36. `logo` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '头像',
  37. `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '密码',
  38. PRIMARY KEY (`id`) USING BTREE,
  39. UNIQUE INDEX `user_id`(`id`, `user_id`) USING BTREE
  40. ) ENGINE = InnoDB AUTO_INCREMENT = 20210513 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '广电庄园 —— 用户信息表' ROW_FORMAT = Dynamic;
  41. -- ----------------------------
  42. -- Records of manor_user
  43. -- ----------------------------
  44. INSERT INTO `manor_user` VALUES (20210511, 1, 30, 1268710, 1, 71120, 10148629, 7, 0, '2021-06-02 11:39:33', 1, 245, 910, 2, 7, '抽奖专用小马甲', 'xxxxxxxxxxxxxxx', 'e10adc3949ba59abbe56e057f20f883e');
  45. SET FOREIGN_KEY_CHECKS = 1;

 三:结束

        到这里,我们可以看出来,集成已经完成,其实也没有几个类,就搞定了token的分发,大家可以直接用项目源码去自己调试一下,每隔模块都写得很清晰。

        demo,我已经测试成功!!!,所以出现问题,一定是你没有配置好,请不要说项目不能使用的话。虚心接受指导,但不接受瞎xxxxx

         码云地址:https://gitee.com/jijiuc/oauth2_securtiy.git

               土豪地址:https://download.csdn.net/download/weixin_38061191/21472467

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/83451
推荐阅读
相关标签
  

闽ICP备14008679号