优化第三方授权登录

feature/model
thiszhc 1 year ago
parent 5110961eb9
commit 005e7df1b8

@ -43,6 +43,12 @@
<artifactId>ruoyi-common-doc</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-social</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-system</artifactId>
@ -75,16 +81,12 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-social</artifactId>
<version>5.1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
<!-- skywalking 整合 logback -->
<!-- <dependency>-->

@ -3,12 +3,9 @@ package org.dromara.web.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.constraints.NotBlank;
import lombok.RequiredArgsConstructor;
import me.zhyd.oauth.cache.AuthStateCache;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
@ -22,10 +19,8 @@ import org.dromara.common.core.domain.model.SmsLoginBody;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.social.config.SocialConfig;
import org.dromara.common.social.config.properties.ConfigProperties;
import org.dromara.common.social.config.properties.SocialLoginConfigProperties;
import org.dromara.common.social.config.properties.SocialProperties;
import org.dromara.common.social.utils.AuthRedisStateCache;
import org.dromara.common.social.utils.SocialUtils;
import org.dromara.common.tenant.helper.TenantHelper;
import org.dromara.system.domain.bo.SysTenantBo;
@ -45,7 +40,6 @@ import org.springframework.web.bind.annotation.*;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.Map;
/**
*
@ -153,7 +147,7 @@ public class AuthController {
{
return R.fail(source + "平台账号已经被账号绑定");
}
ConfigProperties obj = socialProperties.getType().get(source);
SocialLoginConfigProperties obj = socialProperties.getType().get(source);
if (ObjectUtil.isNull(obj)){
return R.fail(source + "平台账号暂不支持");
}
@ -175,7 +169,7 @@ public class AuthController {
@SuppressWarnings("unchecked")
@GetMapping("/social-login/{source}")
public R<String> socialLogin(@PathVariable("source") String source, AuthCallback callback, HttpServletRequest request) throws IOException {
ConfigProperties obj = socialProperties.getType().get(source);
SocialLoginConfigProperties obj = socialProperties.getType().get(source);
if (ObjectUtil.isNull(obj)){
return R.fail(source + "平台账号暂不支持");
}

@ -44,6 +44,7 @@ import org.dromara.system.service.ISocialUserService;
import org.dromara.system.service.ISysPermissionService;
import org.dromara.system.service.ISysTenantService;
import org.dromara.system.service.ISysUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@ -181,27 +182,49 @@ public class SysLoginService {
return R.fail("对不起,授权信息验证不通过,请退出重试!");
}
AuthUser authUserData = authUser.getData();
// 查询社交用户信息,判断是否已经绑定,如果已经绑定则直接登录,否则验证是否登录,未登录则先登录再绑定
SocialUserVo user = socialUserService.selectSocialUserByAuthId(source + authUserData.getUuid());
String authId = source + authUserData.getUuid();
SocialUserVo user = socialUserService.selectSocialUserByAuthId(authId);
if (ObjectUtil.isNotNull(user)) {
checkTenant(user.getTenantId());
SysUserVo dbUser = loadUserByUsername(user.getTenantId(), user.getUserName());
LoginHelper.loginByDevice(buildLoginUser(dbUser), DeviceType.SOCIAL);
recordLogininfor(dbUser.getTenantId(), user.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
recordLoginInfo(user.getUserId());
//执行登录和记录登录信息操作
return loginAndRecord(user.getTenantId(), user.getUserName(), authUserData);
} else {
// 判断是否已登录
if (LoginHelper.getUserId() == null) {
return R.fail("授权失败,请先登录再绑定");
}
SocialUserBo socialUserBo = new SocialUserBo();
socialUserService.insertByBo(setAuthUserData(authUserData, socialUserBo));
socialUserBo.setUserId(LoginHelper.getUserId());
socialUserBo.setAuthId(authUserData.getSource() + authUserData.getUuid());
socialUserBo.setSource(authUserData.getSource());
socialUserBo.setUserName(authUserData.getUsername());
socialUserBo.setNickName(authUserData.getNickname());
socialUserBo.setAvatar(authUserData.getAvatar());
socialUserBo.setOpenId(authUserData.getUuid());
BeanUtils.copyProperties(authUserData, socialUserBo);
BeanUtils.copyProperties(authUserData.getToken(), socialUserBo);
socialUserService.insertByBo(socialUserBo);
SysUserVo lodingData = loadUserByUsername(LoginHelper.getTenantId(), LoginHelper.getUsername());
checkTenant(lodingData.getTenantId());
LoginHelper.loginByDevice(buildLoginUser(lodingData), DeviceType.SOCIAL);
recordLogininfor(lodingData.getTenantId(), socialUserBo.getUserName(), Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
recordLoginInfo(socialUserBo.getUserId());
//执行登录和记录登录信息操作
return loginAndRecord(lodingData.getTenantId(), socialUserBo.getUserName(), authUserData);
}
}
/**
*
*
* @param tenantId ID
* @param userName
* @param authUser
* @return
*/
private R<String> loginAndRecord(String tenantId, String userName, AuthUser authUser) {
checkTenant(tenantId);
SysUserVo dbUser = loadUserByUsername(tenantId, userName);
LoginHelper.loginByDevice(buildLoginUser(dbUser), DeviceType.SOCIAL);
recordLogininfor(dbUser.getTenantId(), userName, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"));
recordLoginInfo(dbUser.getUserId());
return R.ok(StpUtil.getTokenValue());
}
@ -440,29 +463,4 @@ public class SysLoginService {
}
}
public SocialUserBo setAuthUserData(AuthUser authUserData, SocialUserBo socialUser) {
socialUser.setUserId(LoginHelper.getUserId());
socialUser.setAuthId(authUserData.getSource() + authUserData.getUuid());
socialUser.setSource(authUserData.getSource());
socialUser.setUserName(authUserData.getUsername());
socialUser.setNickName(authUserData.getNickname());
socialUser.setAvatar(authUserData.getAvatar());
socialUser.setEmail(authUserData.getEmail());
socialUser.setOpenId(authUserData.getUuid());
socialUser.setAccessToken(authUserData.getToken().getAccessToken());
socialUser.setExpireIn(authUserData.getToken().getExpireIn());
socialUser.setRefreshToken(authUserData.getToken().getRefreshToken());
socialUser.setAccessCode(authUserData.getToken().getAccessCode());
socialUser.setUnionId(authUserData.getToken().getUnionId());
socialUser.setScope(authUserData.getToken().getScope());
socialUser.setTokenType(authUserData.getToken().getTokenType());
socialUser.setIdToken(authUserData.getToken().getIdToken());
socialUser.setMacAlgorithm(authUserData.getToken().getMacAlgorithm());
socialUser.setMacKey(authUserData.getToken().getMacKey());
socialUser.setCode(authUserData.getToken().getCode());
socialUser.setOauthToken(authUserData.getToken().getOauthToken());
socialUser.setOauthTokenSecret(authUserData.getToken().getOauthTokenSecret());
return socialUser;
}
}

@ -117,6 +117,12 @@
<version>${revision}</version>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-social</artifactId>
<version>${revision}</version>
</dependency>
<!-- web服务 -->
<dependency>
<groupId>org.dromara</groupId>

@ -1,35 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common</artifactId>
<version>${revision}</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-common-social</artifactId>
<description>
ruoyi-common-auth 认证模块
ruoyi-common-social 授权认证
</description>
<dependencies>
<dependency>
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.dromara</groupId>
<artifactId>ruoyi-common-redis</artifactId>

@ -17,7 +17,7 @@ import org.springframework.context.annotation.Bean;
public class SocialConfig {
@Bean
public AuthStateCache redis() {
public AuthStateCache authStateCache() {
return new AuthRedisStateCache();
}

@ -3,7 +3,7 @@ package org.dromara.common.social.config.properties;
import lombok.Data;
@Data
public class ConfigProperties {
public class SocialLoginConfigProperties {
/**
* ID

@ -24,7 +24,7 @@ public class SocialProperties {
/**
*
*/
private Map<String, ConfigProperties> type;
private Map<String, SocialLoginConfigProperties> type;
/**
*

@ -12,21 +12,7 @@ import java.time.Duration;
public class AuthRedisStateCache implements AuthStateCache {
private final SocialProperties socialProperties;
private final RedisTemplate<String, String> redisTemplate;
private ValueOperations<String, String> valueOperations;
@PostConstruct
public void init() {
valueOperations = redisTemplate.opsForValue();
}
public AuthRedisStateCache() {
this.socialProperties = new SocialProperties();
redisTemplate = new RedisTemplate<>();
}
private SocialProperties socialProperties;
/**
*

@ -19,17 +19,17 @@ public class SocialUtils {
AuthRequest authRequest = null;
switch (source.toLowerCase()) {
case "dingtalk" ->
authRequest = new AuthDingTalkRequest(AuthConfig.builder().
clientId(clientId).
clientSecret(clientSecret)
.redirectUri(redirectUri).
build());
authRequest = new AuthDingTalkRequest(AuthConfig.builder()
.clientId(clientId)
.clientSecret(clientSecret)
.redirectUri(redirectUri)
.build());
case "baidu" ->
authRequest = new AuthBaiduRequest(AuthConfig.builder().
clientId(clientId).
clientSecret(clientSecret)
.redirectUri(redirectUri).
build());
authRequest = new AuthBaiduRequest(AuthConfig.builder()
.clientId(clientId)
.clientSecret(clientSecret)
.redirectUri(redirectUri)
.build());
case "github" ->
authRequest = new AuthGithubRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
.redirectUri(redirectUri).build());

@ -1,105 +0,0 @@
package org.dromara.system.controller.system;
import java.util.List;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.dromara.common.idempotent.annotation.RepeatSubmit;
import org.dromara.common.log.annotation.Log;
import org.dromara.common.web.core.BaseController;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.validate.AddGroup;
import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.log.enums.BusinessType;
import org.dromara.common.excel.utils.ExcelUtil;
import org.dromara.system.domain.vo.SocialUserVo;
import org.dromara.system.domain.bo.SocialUserBo;
import org.dromara.system.service.ISocialUserService;
import org.dromara.common.mybatis.core.page.TableDataInfo;
/**
*
*
* @author thiszhc
* @date 2023-06-12
*/
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/system/socialUser")
public class SocialUserController extends BaseController {
private final ISocialUserService socialUserService;
/**
*
*/
@SaCheckPermission("system:user:list")
@GetMapping("/list")
public TableDataInfo<SocialUserVo> list(SocialUserBo bo, PageQuery pageQuery) {
return socialUserService.queryPageList(bo, pageQuery);
}
/**
*
*/
@SaCheckPermission("system:user:export")
@Log(title = "社会化关系", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(SocialUserBo bo, HttpServletResponse response) {
List<SocialUserVo> list = socialUserService.queryList(bo);
ExcelUtil.exportExcel(list, "社会化关系", SocialUserVo.class, response);
}
/**
*
*
* @param id
*/
@SaCheckPermission("system:user:query")
@GetMapping("/{id}")
public R<SocialUserVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
return R.ok(socialUserService.queryById(id));
}
/**
*
*/
@SaCheckPermission("system:user:add")
@Log(title = "社会化关系", businessType = BusinessType.INSERT)
@RepeatSubmit()
@PostMapping()
public R<Void> add(@Validated(AddGroup.class) @RequestBody SocialUserBo bo) {
return toAjax(socialUserService.insertByBo(bo));
}
/**
*
*/
@SaCheckPermission("system:user:edit")
@Log(title = "社会化关系", businessType = BusinessType.UPDATE)
@RepeatSubmit()
@PutMapping()
public R<Void> edit(@Validated(EditGroup.class) @RequestBody SocialUserBo bo) {
return toAjax(socialUserService.updateByBo(bo));
}
/**
*
*
* @param ids
*/
@SaCheckPermission("system:user:remove")
@Log(title = "社会化关系", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public R<Void> remove(@NotEmpty(message = "主键不能为空")
@PathVariable Long[] ids) {
return toAjax(socialUserService.deleteWithValidByIds(List.of(ids), true));
}
}

@ -19,35 +19,11 @@ import java.util.List;
*/
public interface ISocialUserService {
/**
*
*/
SocialUserVo queryById(Long id);
/**
*
*/
TableDataInfo<SocialUserVo> queryPageList(SocialUserBo bo, PageQuery pageQuery);
/**
*
*/
List<SocialUserVo> queryList(SocialUserBo bo);
/**
*
*/
Boolean insertByBo(SocialUserBo bo);
/**
*
*/
Boolean updateByBo(SocialUserBo bo);
/**
*
*/
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
/**
*

@ -33,56 +33,6 @@ public class SocialUserServiceImpl implements ISocialUserService {
private final SocialUserMapper baseMapper;
/**
*
*/
@Override
public SocialUserVo queryById(Long id) {
return baseMapper.selectVoById(id);
}
/**
*
*/
@Override
public TableDataInfo<SocialUserVo> queryPageList(SocialUserBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<SocialUser> lqw = buildQueryWrapper(bo);
Page<SocialUserVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
*
*/
@Override
public List<SocialUserVo> queryList(SocialUserBo bo) {
LambdaQueryWrapper<SocialUser> lqw = buildQueryWrapper(bo);
return baseMapper.selectVoList(lqw);
}
private LambdaQueryWrapper<SocialUser> buildQueryWrapper(SocialUserBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<SocialUser> lqw = Wrappers.lambdaQuery();
lqw.eq(StringUtils.isNotBlank(bo.getAuthId()), SocialUser::getAuthId, bo.getAuthId());
lqw.eq(StringUtils.isNotBlank(bo.getSource()), SocialUser::getSource, bo.getSource());
lqw.eq(StringUtils.isNotBlank(bo.getAccessToken()), SocialUser::getAccessToken, bo.getAccessToken());
lqw.eq(bo.getExpireIn() != 0, SocialUser::getExpireIn, bo.getExpireIn());
lqw.eq(StringUtils.isNotBlank(bo.getRefreshToken()), SocialUser::getRefreshToken, bo.getRefreshToken());
lqw.eq(StringUtils.isNotBlank(bo.getOpenId()), SocialUser::getOpenId, bo.getOpenId());
lqw.eq(StringUtils.isNotBlank(bo.getScope()), SocialUser::getScope, bo.getScope());
lqw.eq(StringUtils.isNotBlank(bo.getAccessCode()), SocialUser::getAccessCode, bo.getAccessCode());
lqw.eq(StringUtils.isNotBlank(bo.getUnionId()), SocialUser::getUnionId, bo.getUnionId());
lqw.eq(StringUtils.isNotBlank(bo.getScope()), SocialUser::getScope, bo.getScope());
lqw.eq(StringUtils.isNotBlank(bo.getTokenType()), SocialUser::getTokenType, bo.getTokenType());
lqw.eq(StringUtils.isNotBlank(bo.getIdToken()), SocialUser::getIdToken, bo.getIdToken());
lqw.eq(StringUtils.isNotBlank(bo.getMacAlgorithm()), SocialUser::getMacAlgorithm, bo.getMacAlgorithm());
lqw.eq(StringUtils.isNotBlank(bo.getMacKey()), SocialUser::getMacKey, bo.getMacKey());
lqw.eq(StringUtils.isNotBlank(bo.getCode()), SocialUser::getCode, bo.getCode());
lqw.eq(StringUtils.isNotBlank(bo.getOauthToken()), SocialUser::getOauthToken, bo.getOauthToken());
lqw.eq(StringUtils.isNotBlank(bo.getOauthTokenSecret()), SocialUser::getOauthTokenSecret, bo.getOauthTokenSecret());
return lqw;
}
/**
*
*/
@ -97,15 +47,6 @@ public class SocialUserServiceImpl implements ISocialUserService {
return flag;
}
/**
*
*/
@Override
public Boolean updateByBo(SocialUserBo bo) {
SocialUser update = MapstructUtils.convert(bo, SocialUser.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
/**
*
@ -114,16 +55,6 @@ public class SocialUserServiceImpl implements ISocialUserService {
//TODO 做一些数据校验,如唯一约束
}
/**
*
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
if (isValid) {
//TODO 做一些业务上的校验,判断是否需要校验
}
return baseMapper.deleteBatchIds(ids) > 0;
}
/**
*

@ -8,61 +8,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<id property="id" column="id"/>
</resultMap>
<sql id="selectSocialUser">
select id,
user_id,
tenant_id,
auth_id,
source,
open_id,
access_token,
expire_in,
refresh_token,
access_code,
union_id,
scope,
token_type,
id_token,
mac_algorithm,
mac_key,
code,
oauth_token,
oauth_token_secret,
create_dept,
create_by,
create_time,
update_by,
update_time
from social_user
</sql>
<!-- 根据userId查询SocialUser表对应userId的SysUser返回SysUserBo的对象 -->
<select id="selectSocialUserByUserId" parameterType="String" resultMap="SocialUserAuthResult">
select b.*
from social_user a
left join sys_user b on a.user_id = b.user_id
where a.user_id = #{userId}
</select>
<!-- 根据authId查询SocialUser表和SysUser表返回SocialUserAuthResult映射的对象 -->
<select id="selectSocialUserByAuthId" parameterType="String" resultMap="SocialUserAuthResult">
select b.user_id as userId,
b.tenant_id as tenantId,
b.user_name as userName,
b.password as password,
a.auth_id as authId,
a.source as source
select b.user_id,
b.tenant_id,
b.user_name,
b.password,
a.auth_id,
a.source
from social_user a
left join sys_user b on a.user_id = b.user_id
left join sys_user b on a.user_id = b.user_id
where a.auth_id = #{authId}
</select>
<!-- 根据userId和source查询SocialUser表返回int类型的结果 -->
<select id="checkSocialUser" parameterType="org.dromara.system.domain.vo.SocialUserVo" resultType="int">
select count(*)
from social_user
where user_id = #{userId} and source = #{source} limit 1
</select>
</mapper>

@ -1,43 +1,40 @@
-- ----------------------------
-- 第三方平台授权表
-- ----------------------------
CREATE TABLE `social_user`
DROP TABLE IF EXISTS social_user;
CREATE TABLE social_user
(
`id` bigint unsigned NOT NULL COMMENT '主键',
`user_id` bigint NOT NULL COMMENT '用户ID',
`tenant_id` varchar(20) DEFAULT NULL COMMENT '租户id',
`auth_id` varchar(255) NOT NULL COMMENT '授权+授权openid',
`source` varchar(255) NOT NULL COMMENT '用户来源',
`open_id` varchar(255) DEFAULT NULL COMMENT '原生open id',
`user_name` varchar(30) NOT NULL COMMENT '登录账号',
`nick_name` varchar(30) DEFAULT '' COMMENT '用户昵称',
`email` varchar(255) DEFAULT '' COMMENT '用户邮箱',
`avatar` varchar(500) DEFAULT '' COMMENT '头像地址',
`access_token` varchar(255) NOT NULL COMMENT '用户的授权令牌',
`expire_in` int DEFAULT NULL COMMENT '用户的授权令牌的有效期,部分平台可能没有',
`refresh_token` varchar(255) DEFAULT NULL COMMENT '刷新令牌,部分平台可能没有',
`access_code` varchar(255) DEFAULT NULL COMMENT '平台的授权信息,部分平台可能没有',
`union_id` varchar(255) DEFAULT NULL COMMENT '用户的 unionid',
`scope` varchar(255) DEFAULT NULL COMMENT '授予的权限,部分平台可能没有',
`token_type` varchar(255) DEFAULT NULL COMMENT '个别平台的授权信息,部分平台可能没有',
`id_token` varchar(255) DEFAULT NULL COMMENT 'id token部分平台可能没有',
`mac_algorithm` varchar(255) DEFAULT NULL COMMENT '小米平台用户的附带属性,部分平台可能没有',
`mac_key` varchar(255) DEFAULT NULL COMMENT '小米平台用户的附带属性,部分平台可能没有',
`code` varchar(255) DEFAULT NULL COMMENT '用户的授权code部分平台可能没有',
`oauth_token` varchar(255) DEFAULT NULL COMMENT 'Twitter平台用户的附带属性部分平台可能没有',
`oauth_token_secret` varchar(255) DEFAULT NULL COMMENT 'Twitter平台用户的附带属性部分平台可能没有',
`create_dept` bigint DEFAULT NULL COMMENT '创建部门',
`create_by` bigint NOT NULL COMMENT '创建人',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` bigint NOT NULL COMMENT '更新人',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '0' COMMENT '删除标志0代表存在 2代表删除',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci
ROW_FORMAT = DYNAMIC COMMENT ='社会化关系表';
id BIGINT UNSIGNED NOT NULL COMMENT '主键',
user_id BIGINT NOT NULL COMMENT '用户ID',
tenant_id VARCHAR(20) DEFAULT NULL COMMENT '租户id',
auth_id VARCHAR(255) NOT NULL COMMENT '授权+授权openid',
source VARCHAR(255) NOT NULL COMMENT '用户来源',
open_id VARCHAR(255) DEFAULT NULL COMMENT '原生open id',
user_name VARCHAR(30) NOT NULL COMMENT '登录账号',
nick_name VARCHAR(30) DEFAULT '' COMMENT '用户昵称',
email VARCHAR(255) DEFAULT '' COMMENT '用户邮箱',
avatar VARCHAR(500) DEFAULT '' COMMENT '头像地址',
access_token VARCHAR(255) NOT NULL COMMENT '用户的授权令牌',
expire_in INT DEFAULT NULL COMMENT '用户的授权令牌的有效期,部分平台可能没有',
refresh_token VARCHAR(255) DEFAULT NULL COMMENT '刷新令牌,部分平台可能没有',
access_code VARCHAR(255) DEFAULT NULL COMMENT '平台的授权信息,部分平台可能没有',
union_id VARCHAR(255) DEFAULT NULL COMMENT '用户的 unionid',
scope VARCHAR(255) DEFAULT NULL COMMENT '授予的权限,部分平台可能没有',
token_type VARCHAR(255) DEFAULT NULL COMMENT '个别平台的授权信息,部分平台可能没有',
id_token VARCHAR(255) DEFAULT NULL COMMENT 'id token部分平台可能没有',
mac_algorithm VARCHAR(255) DEFAULT NULL COMMENT '小米平台用户的附带属性,部分平台可能没有',
mac_key VARCHAR(255) DEFAULT NULL COMMENT '小米平台用户的附带属性,部分平台可能没有',
code VARCHAR(255) DEFAULT NULL COMMENT '用户的授权code部分平台可能没有',
oauth_token VARCHAR(255) DEFAULT NULL COMMENT 'Twitter平台用户的附带属性部分平台可能没有',
oauth_token_secret VARCHAR(255) DEFAULT NULL COMMENT 'Twitter平台用户的附带属性部分平台可能没有',
create_dept bigint(20) comment '创建部门',
create_by bigint(20) comment '创建者',
create_time datetime comment '创建时间',
update_by bigint(20) comment '更新者',
update_time datetime comment '更新时间',
del_flag char(1) default '0' comment '删除标志0代表存在 2代表删除',
PRIMARY KEY (id)
) ENGINE = InnoDB COMMENT ='社会化关系表';
-- ----------------------------
-- 租户表

Loading…
Cancel
Save