SpringCloud Security, OAuth2, JWT 实现认证和授权(二)

1、配置用户,即创建个人用户凭据和所属角色

/**
 * 配置用户
 * 验证用户的机制,并返回正在验证的用户的信息
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled=true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    /**
     * 使用 Security 认证管理器
     * @return
     * @throws Exception
     */
    @Override
    @Bean
    public AuthenticationManager authenticationManager() throws Exception {
        return super.authenticationManager();
    }

    /**
     * security 密码加密
     * @return
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    @Override
    public UserDetailsService userDetailsService() {
        return new UserDetailsServiceImpl();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService());
    }

    /**
     * 配置security不拦截的请求
     * 将check_token暴露出去,否则资源服务器访问时报403错误
     * @param web
     * @throws Exception
     */
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring()
            .antMatchers("/auth/login",
            "/oauth/check_token");
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        //禁止跨域请求
        http.csrf().disable()
                .httpBasic()
                .and()
                .formLogin()
                .and()
                .authorizeRequests().anyRequest().authenticated();
    }
}

2、自定义用户认证与授权

/**
 * 自定义用户认证与授权
 * @author suoyx
 * @date 2021/3/21 19:06
 */
public class UserDetailsServiceImpl implements UserDetailsService {

    @Resource
    private AuthUserService authUserService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        AuthUser authUser = authUserService.findByUserName(username);
        // 用户权限
        Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
        List<Menu> menuList = authUserService.listMenuByUserId(authUser.getId());
        menuList.forEach(SysMenu -> {
            if (StringUtils.isNotBlank(SysMenu.getResource())) {
                GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(SysMenu.getResource());
                grantedAuthorities.add(grantedAuthority);
            }
        });
        // 构建返回信息
        JwtUser jwtUser = new JwtUser(authUser.getUserName(), authUser.getPassword(), grantedAuthorities);
        jwtUser.setId(authUser.getId());
        jwtUser.setUsername(authUser.getUserName());
        return jwtUser;
    }

}

3、自定义用户认证与授权

UserDetailsServiceImpl类实现UserDetailsService接口,重写loadUserByUsername方法

public class UserDetailsServiceImpl implements UserDetailsService {

    @Resource
    private AuthUserService authUserService;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        AuthUser authUser = authUserService.findByUserName(username);
        // 用户权限
        Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
        List<Menu> menuList = authUserService.listMenuByUserId(authUser.getId());
        menuList.forEach(SysMenu -> {
            if (StringUtils.isNotBlank(SysMenu.getResource())) {
                GrantedAuthority grantedAuthority = new SimpleGrantedAuthority(SysMenu.getResource());
                grantedAuthorities.add(grantedAuthority);
            }
        });
        // 构建返回信息
        JwtUser jwtUser = new JwtUser(authUser.getUserName(), authUser.getPassword(), grantedAuthorities);
        jwtUser.setId(authUser.getId());
        jwtUser.setUsername(authUser.getUserName());
        return jwtUser;
    }

}

自定义用户信息:

@Data
public class JwtUser extends User {
    private Long id;

    private String username;

    public JwtUser(String username, String password, Collection<? extends GrantedAuthority> authorities) {
        super(username, password, authorities);
    }

}

用户和权限相关的接口和实现类:

public interface AuthUserService {
    /**
     * 根据用户名查询当前用户是否存在
     * @param name
     * @return
     */
    AuthUser findByUserName(String name);

    /**
     * 根据用户id查询当前用户拥有的权限
     * @param userId 用户id
     * @return
     */
    List<Menu> listMenuByUserId(long userId);
}
@Service
public class AuthUserServiceImpl implements AuthUserService {
    @Autowired
    AuthUserMapper authUserMapper;

    @Autowired
    UserRoleMapper userRoleMapper;

    @Autowired
    RoleMenuMapper roleMenuMapper;

    @Autowired
    private MenuMapper menuMapper;

    @Override
    public AuthUser findByUserName(String name) {
        LambdaQueryWrapper<AuthUser> lambda = new QueryWrapper<AuthUser>().lambda();
        lambda.eq(AuthUser::getUserName, name);
        return authUserMapper.selectOne(lambda);
    }

    @Override
    public List<Menu> listMenuByUserId(long userId) {
        // 筛选出所有的角色id
        LambdaQueryWrapper<UserRole> lambda = new QueryWrapper<UserRole>().lambda();
        lambda.eq(UserRole::getAuthUserId, userId);
        List<UserRole> roleUsers = userRoleMapper.selectList(lambda);
        // 筛选出所有的角色id
        List<Long> roleIds = roleUsers.stream().map(UserRole::getRoleId).collect(Collectors.toList());
        //根据角色来查询对应的菜单
        LambdaQueryWrapper<RoleMenu> roleWrapper = new QueryWrapper<RoleMenu>().lambda();
        roleWrapper.in(RoleMenu::getRoleId, roleIds);
        List<RoleMenu> menuList = roleMenuMapper.selectList(roleWrapper);
        //筛选所有的权限id
        List<Long> menu = menuList.stream().map(RoleMenu::getMenuId).collect(Collectors.toList());
        LambdaQueryWrapper<Menu> menuWrapper = new QueryWrapper<Menu>().lambda();
        menuWrapper.in(Menu::getId, menu);
        menuWrapper.eq(Menu::getLogicalDeleted, 1);
        return menuMapper.selectList(menuWrapper);
    }
}

对应的Mapper和Entity实体:

@Repository
public interface AuthUserMapper extends BaseMapper<AuthUser> {
}
@Repository
public interface MenuMapper extends BaseMapper<Menu> {
}
@Repository
public interface RoleMenuMapper extends BaseMapper<RoleMenu> {
}
@Repository
public interface UserRoleMapper extends BaseMapper<UserRole> {
}

实体类:

个人账号实体类:

@Data
@TableName(value = "user")
public class AuthUser extends BaseModel {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    /**
     * 用户名称
     */
    @TableField(value = "user_name")
    private String userName;

    /**
     * 用户密码
     */
    @TableField(value = "password")
    private String password;

    /**
     * 手机号
     */
    @TableField(value = "mobile_phone")
    private String mobilePhone;


    /**
     * 用户状态1.启用2.禁用
     */
    @TableField(value = "state")
    private Byte state;

    /**
     * 微信openid
     */
    @TableField(value = "open_id")
    private String openId;

    /**
     * 过期时间
     */
    @TableField(value = "expire_time")
    private Date expireTime;

}
菜单实体类:
@Data
@TableName(value = "menu")
public class Menu extends BaseModel {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    /**
     * 菜单和API接口名称
     */
    @TableField(value = "title")
    private String title;

    /**
     * 路径
     */
    @TableField(value = "path")
    private String path;

    /**
     * 图标
     */
    @TableField(value = "icon")
    private String icon;

    /**
     * 类型1.菜单2.API接口
     */
    @TableField(value = "type")
    private Byte type;

    /**
     * 按钮显示code
     */
    @TableField(value = "code")
    private String code;

    /**
     * 父级菜单id
     */
    @TableField(value = "parent_id")
    private Long parentId;

    /**
     * 是否是系统菜单1.是2.不是
     */
    @TableField(value = "is_system_menu")
    private Byte isSystemMenu;

    /**
     * 权限码
     */
    @TableField(value = "resource")
    private String resource;

    /**
     * 排序号
     */
    @TableField(value = "sort")
    private Long sort;

}
角色和菜单关系类:
@Data
@TableName(value = "role_menu")
public class RoleMenu extends BaseModel {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.INPUT)
    private Long id;

    /**
     * 角色id
     */
    @TableField(value = "role_id")
    private Long roleId;

    /**
     * 菜单和API接口id
     */
    @TableField(value = "menu_id")
    private Long menuId;

}

用户和角色关系实体类:

@Data
@TableName(value = "user_role")
public class UserRole extends BaseModel {
    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    /**
     * 用户账号id
     */
    @TableField(value = "auth_user_id")
    private Long authUserId;

    /**
     * 角色id
     */
    @TableField(value = "role_id")
    private Long roleId;
}

4、准备数据

扫描二维码关注公众号,回复: 13123424 查看本文章

/*
Navicat MySQL Data Transfer

Source Server         : localhost_3306
Source Server Version : 50625
Source Host           : localhost:3306
Source Database       : springcloud

Target Server Type    : MYSQL
Target Server Version : 50625
File Encoding         : 65001

Date: 2021-03-28 23:10:39
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `menu`
-- ----------------------------
DROP TABLE IF EXISTS `menu`;
CREATE TABLE `menu` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
  `title` varchar(50) NOT NULL COMMENT '菜单或者按钮名称',
  `path` varchar(255) NOT NULL COMMENT '路径',
  `icon` varchar(255) NOT NULL COMMENT '图标',
  `type` tinyint(4) unsigned NOT NULL COMMENT '类型1.菜单2.按钮3.元素',
  `code` varchar(50) NOT NULL DEFAULT '' COMMENT '按钮显示code',
  `parent_id` bigint(20) NOT NULL COMMENT '父级菜单id',
  `is_system_menu` tinyint(4) unsigned NOT NULL COMMENT '是否是系统菜单1.是2.不是(业务菜单)',
  `resource` varchar(255) NOT NULL DEFAULT '' COMMENT '权限',
  `sort` tinyint(4) NOT NULL COMMENT '排序',
  `create_by` bigint(20) NOT NULL COMMENT '创建人id',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `last_modify_by` bigint(20) NOT NULL COMMENT '上次修改人id',
  `last_modify_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '上次修改时间',
  `logical_deleted` tinyint(4) NOT NULL DEFAULT '1' COMMENT '逻辑删除1.正常2.已删除',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

-- ----------------------------
-- Records of menu
-- ----------------------------
INSERT INTO `menu` VALUES ('1', '库存分析', '/1', '1', '1', '1', '0', '1', '1', '0', '1', '2021-01-29 15:03:08', '1', '2021-01-29 15:03:08', '0');
INSERT INTO `menu` VALUES ('2', '订单分析', '/2', '2', '1', '1', '0', '1', '2', '0', '1', '2021-01-29 15:03:08', '1', '2021-01-29 15:03:08', '0');
INSERT INTO `menu` VALUES ('3', '后台管理', '/3', '3', '1', '1', '0', '1', '3', '0', '1', '2021-01-29 15:03:08', '1', '2021-01-29 15:03:08', '0');
INSERT INTO `menu` VALUES ('4', '库存数量', '/4', '4', '1', '1', '1', '1', '4', '0', '1', '2021-01-29 15:03:08', '1', '2021-01-29 15:03:08', '0');
INSERT INTO `menu` VALUES ('5', '库存总额', '/5', '4', '1', '1', '1', '1', '5', '0', '1', '2021-01-29 15:03:08', '1', '2021-01-29 15:03:08', '0');
INSERT INTO `menu` VALUES ('6', '库存信息', '/6', '4', '1', '1', '1', '1', '6', '0', '1', '2021-01-29 15:03:08', '1', '2021-01-29 15:03:08', '0');

-- ----------------------------
-- Table structure for `oauth_client_details`
-- ----------------------------
DROP TABLE IF EXISTS `oauth_client_details`;
CREATE TABLE `oauth_client_details` (
  `client_id` varchar(128) NOT NULL,
  `resource_ids` varchar(256) DEFAULT NULL,
  `client_secret` varchar(256) DEFAULT NULL,
  `scope` varchar(256) DEFAULT NULL,
  `authorized_grant_types` varchar(256) DEFAULT NULL,
  `web_server_redirect_uri` varchar(256) DEFAULT NULL,
  `authorities` varchar(256) DEFAULT NULL,
  `access_token_validity` int(11) DEFAULT NULL,
  `refresh_token_validity` int(11) DEFAULT NULL,
  `additional_information` varchar(4096) DEFAULT NULL,
  `autoapprove` varchar(256) DEFAULT NULL,
  PRIMARY KEY (`client_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;

-- ----------------------------
-- Records of oauth_client_details
-- ----------------------------
INSERT INTO `oauth_client_details` VALUES ('client', null, '$2a$10$rfjh0xBSbAih956yoisDFOFKVNjJzByET0ShRNzVs9M9oqQQlvjki', 'web', 'authorization_code,password,refresh_token,client_credentials', '', null, null, null, null, 'true');

-- ----------------------------
-- Table structure for `role`
-- ----------------------------
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
  `name` varchar(32) NOT NULL COMMENT '角色名称',
  `description` varchar(255) NOT NULL COMMENT '部门简述',
  `state` tinyint(4) unsigned NOT NULL COMMENT '角色状态1.启用2.禁用',
  `type` tinyint(4) DEFAULT NULL COMMENT '1.后台2.前台',
  `create_by` bigint(20) DEFAULT NULL COMMENT '创建人id',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `last_modify_by` bigint(20) DEFAULT NULL COMMENT '上次修改人id',
  `last_modify_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '上次修改时间',
  `logical_deleted` tinyint(4) DEFAULT '1' COMMENT '逻辑删除1.正常2.已删除',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

-- ----------------------------
-- Records of role
-- ----------------------------
INSERT INTO `role` VALUES ('1', '角色1', '角色1', '1', '1', '2', '2021-01-29 15:03:08', '2', '2021-01-29 15:03:08', '0');
INSERT INTO `role` VALUES ('2', '角色2', '角色2', '1', '1', '2', '2021-01-29 15:03:08', null, '2021-01-29 15:03:08', '0');
INSERT INTO `role` VALUES ('3', '角色3', '角色3', '1', '1', '2', '2021-01-29 15:03:08', '2', '2021-01-29 15:03:08', '0');

-- ----------------------------
-- Table structure for `role_menu`
-- ----------------------------
DROP TABLE IF EXISTS `role_menu`;
CREATE TABLE `role_menu` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
  `role_id` bigint(20) unsigned NOT NULL COMMENT '角色id',
  `menu_id` bigint(20) unsigned NOT NULL COMMENT '菜单或者按钮id',
  `create_by` bigint(20) NOT NULL COMMENT '创建人id',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `last_modify_by` bigint(20) NOT NULL COMMENT '上次修改人id',
  `last_modify_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '上次修改时间',
  `logical_deleted` tinyint(4) NOT NULL DEFAULT '1' COMMENT '逻辑删除1.正常2.已删除',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=28 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

-- ----------------------------
-- Records of role_menu
-- ----------------------------
INSERT INTO `role_menu` VALUES ('1', '1', '1', '2', '2021-01-29 15:03:08', '2', '2021-01-29 15:03:08', '0');
INSERT INTO `role_menu` VALUES ('2', '1', '2', '2', '2021-01-29 15:03:08', '2', '2021-01-29 15:03:08', '0');
INSERT INTO `role_menu` VALUES ('3', '1', '3', '2', '2021-01-29 15:03:08', '2', '2021-01-29 15:03:08', '0');
INSERT INTO `role_menu` VALUES ('4', '1', '4', '2', '2021-01-29 15:03:08', '2', '2021-01-29 15:03:08', '0');
INSERT INTO `role_menu` VALUES ('5', '2', '1', '2', '2021-01-29 15:03:08', '2', '2021-01-29 15:03:08', '0');
INSERT INTO `role_menu` VALUES ('6', '2', '2', '2', '2021-01-29 15:03:08', '2', '2021-01-29 15:03:08', '0');
INSERT INTO `role_menu` VALUES ('7', '2', '6', '2', '2021-01-29 15:03:08', '2', '2021-01-29 15:03:08', '0');
INSERT INTO `role_menu` VALUES ('8', '3', '5', '2', '2021-01-29 15:03:08', '2', '2021-01-29 15:03:08', '0');

-- ----------------------------
-- Table structure for `user`
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
  `user_name` varchar(20) NOT NULL DEFAULT '' COMMENT '用户名称',
  `password` varchar(300) NOT NULL COMMENT '用户密码',
  `mobile_phone` char(11) NOT NULL DEFAULT '' COMMENT '手机号',
  `state` tinyint(4) NOT NULL COMMENT '用户状态1.启用2.禁用',
  `open_id` varchar(50) NOT NULL DEFAULT '' COMMENT '微信openid\n',
  `expire_time` datetime DEFAULT NULL COMMENT '过期时间',
  `create_by` bigint(20) NOT NULL COMMENT '创建人id',
  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `last_modify_by` bigint(20) NOT NULL DEFAULT '0' COMMENT '上次修改人id',
  `last_modify_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '上次修改时间',
  `logical_deleted` tinyint(4) NOT NULL DEFAULT '1' COMMENT '逻辑删除1.正常2.已删除',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', 'admin', '$2a$10$sIj/zvXEJiuXIdYQuyNzEuaJsvRFmVTmsBdOX3NA//acFc7KmY3Yu', '11111111112', '1', '', '2030-01-01 00:00:00', '1', '2021-01-29 15:03:08', '1', '2021-01-29 15:03:08', '0');
INSERT INTO `user` VALUES ('2', 'cindy', '$2a$10$oid8x9NsqRcmr8GN54bDhuVI.qwbY2zsaKxYYrZiwqGH6tImpCtjy', '11111111111', '1', '', '2030-01-01 00:00:00', '1', '2021-01-29 15:03:08', '1', '2021-01-29 15:03:08', '0');
INSERT INTO `user` VALUES ('3', 'alice', '$2a$10$H7FKVYN0394QlPpMMISCBu2Z/3wm7C01gnWCn6hpl5LR.ksYEuyeO', '11111111111', '1', '', '2030-01-01 00:00:00', '1', '2021-01-29 15:03:08', '1', '2021-01-29 15:03:08', '0');

-- ----------------------------
-- Table structure for `user_role`
-- ----------------------------
DROP TABLE IF EXISTS `user_role`;
CREATE TABLE `user_role` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
  `auth_user_id` bigint(20) unsigned NOT NULL COMMENT '员工id',
  `role_id` bigint(20) unsigned NOT NULL COMMENT '角色id',
  `create_by` bigint(20) NOT NULL COMMENT '创建人id',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `last_modify_by` bigint(20) DEFAULT NULL COMMENT '上次修改人id',
  `last_modify_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '上次修改时间',
  `logical_deleted` tinyint(4) NOT NULL DEFAULT '1' COMMENT '逻辑删除1.正常2.已删除',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC;

-- ----------------------------
-- Records of user_role
-- ----------------------------
INSERT INTO `user_role` VALUES ('1', '1', '1', '2', '2021-01-29 15:03:08', '2', '2021-01-29 15:03:08', '0');
INSERT INTO `user_role` VALUES ('2', '1', '2', '1', '2021-01-29 15:03:08', '1', '2021-01-29 15:03:08', '0');
INSERT INTO `user_role` VALUES ('3', '1', '3', '1', '2021-01-29 15:03:08', '1', '2021-01-29 15:03:08', '0');
INSERT INTO `user_role` VALUES ('4', '2', '1', '2', '2021-01-29 15:03:08', '2', '2021-01-29 15:03:08', '0');
INSERT INTO `user_role` VALUES ('5', '2', '2', '1', '2021-01-29 15:03:08', '1', '2021-01-29 15:03:08', '0');
INSERT INTO `user_role` VALUES ('6', '3', '1', '1', '2021-01-29 15:03:08', '1', '2021-01-29 15:03:08', '0');
 

5、获得token,使用postman请求http://localhost:9090/oauth/token

Authorization选项卡里type选择Basic Auth,username为client,password为admin

Body选项卡里设置,选中x-www-form-urlencoded,输入四个键值对:

grant_type:password

username:cindy

password:456

scope:web

返回结果:

{
    "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MTY5NzY3MjIsInVzZXJfbmFtZSI6ImNpbmR5IiwiYXV0aG9yaXRpZXMiOlsiMSIsIjIiLCIzIiwiNCIsIjYiXSwianRpIjoiZjBmYzM3ZGYtMzA5Ni00YjBmLWFjNDAtZTAyYWU5YzVkOGRmIiwiY2xpZW50X2lkIjoiY2xpZW50Iiwic2NvcGUiOlsid2ViIl19.c-RpDGlbWe8etnDa915zlDwu7dW0hwGKN1SHUVvWX-E",
    "token_type": "bearer",
    "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX25hbWUiOiJjaW5keSIsInNjb3BlIjpbIndlYiJdLCJhdGkiOiJmMGZjMzdkZi0zMDk2LTRiMGYtYWM0MC1lMDJhZTljNWQ4ZGYiLCJleHAiOjE2MTk1MjU1MjIsImF1dGhvcml0aWVzIjpbIjEiLCIyIiwiMyIsIjQiLCI2Il0sImp0aSI6IjA5YTcwNWQxLWViNmItNGM4Mi1hZTBlLWM1MDU1NjI5MDIzOSIsImNsaWVudF9pZCI6ImNsaWVudCJ9.sGbW--SPTztAsqOJ49HAOBRycU_Bk1qtGlcW21IBh6o",
    "expires_in": 43199,
    "scope": "web",
    "jti": "f0fc37df-3096-4b0f-ac40-e02ae9c5d8df"
}

access_token:

token_type:

refresh_token:

expires_in:

scope:

jti:

猜你喜欢

转载自blog.csdn.net/suoyx/article/details/115289387