三方登录学习

三方登录

SpringBoot 实现App第三方微信登录 - uzxin - 博客园 (cnblogs.com)

(81条消息) OAuth三方授权登录_Java知音_的博客-CSDN博客

创建数据库表

-- ----------------------------
-- 第三方平台授权表
-- ----------------------------
create table sys_social
(
    id                 int8             not null,
    user_id            int8             not null,
    tenant_id          varchar(20)      default null::varchar,
    auth_id            varchar(255)     not null,
    source             varchar(255)     not null,
    open_id            varchar(255)     default null::varchar,
    user_name          varchar(30)      not null,
    nick_name          varchar(30)      default ''::varchar,
    email              varchar(255)     default ''::varchar,
    avatar             varchar(500)     default ''::varchar,
    access_token       varchar(255)     not null,
    expire_in          int8             default null,
    refresh_token      varchar(255)     default null::varchar,
    access_code        varchar(255)     default null::varchar,
    union_id           varchar(255)     default null::varchar,
    scope              varchar(255)     default null::varchar,
    token_type         varchar(255)     default null::varchar,
    id_token           varchar(255)     default null::varchar,
    mac_algorithm      varchar(255)     default null::varchar,
    mac_key            varchar(255)     default null::varchar,
    code               varchar(255)     default null::varchar,
    oauth_token        varchar(255)     default null::varchar,
    oauth_token_secret varchar(255)     default null::varchar,
    create_dept        int8,
    create_by          int8,
    create_time        timestamp,
    update_by          int8,
    update_time        timestamp,
    del_flag           char             default '0'::bpchar,
    constraint "pk_sys_social" primary key (id)
);

comment on table   sys_social                   is '社会化关系表';
comment on column  sys_social.id                is '主键';
comment on column  sys_social.user_id           is '用户ID';
comment on column  sys_social.tenant_id         is '租户id';
comment on column  sys_social.auth_id           is '平台+平台唯一id';
comment on column  sys_social.source            is '用户来源';
comment on column  sys_social.open_id           is '平台编号唯一id';
comment on column  sys_social.user_name         is '登录账号';
comment on column  sys_social.nick_name         is '用户昵称';
comment on column  sys_social.email             is '用户邮箱';
comment on column  sys_social.avatar            is '头像地址';
comment on column  sys_social.access_token      is '用户的授权令牌';
comment on column  sys_social.expire_in         is '用户的授权令牌的有效期,部分平台可能没有';
comment on column  sys_social.refresh_token     is '刷新令牌,部分平台可能没有';
comment on column  sys_social.access_code       is '平台的授权信息,部分平台可能没有';
comment on column  sys_social.union_id          is '用户的 unionid';
comment on column  sys_social.scope             is '授予的权限,部分平台可能没有';
comment on column  sys_social.token_type        is '个别平台的授权信息,部分平台可能没有';
comment on column  sys_social.id_token          is 'id token,部分平台可能没有';
comment on column  sys_social.mac_algorithm     is '小米平台用户的附带属性,部分平台可能没有';
comment on column  sys_social.mac_key           is '小米平台用户的附带属性,部分平台可能没有';
comment on column  sys_social.code              is '用户的授权code,部分平台可能没有';
comment on column  sys_social.oauth_token       is 'Twitter平台用户的附带属性,部分平台可能没有';
comment on column  sys_social.oauth_token_secret is 'Twitter平台用户的附带属性,部分平台可能没有';
comment on column  sys_social.create_dept       is '创建部门';
comment on column  sys_social.create_by         is '创建者';
comment on column  sys_social.create_time       is '创建时间';
comment on column  sys_social.update_by         is '更新者';
comment on column  sys_social.update_time       is '更新时间';
comment on column  sys_social.del_flag          is '删除标志(0代表存在 2代表删除)';

导入<justauth.version>1.16.5</justauth.version>

            <!-- JustAuth 的依赖配置-->
            <dependency>
                <groupId>me.zhyd.oauth</groupId>
                <artifactId>JustAuth</artifactId>
                <version>${justauth.version}</version>
            </dependency>

配置yml

--- # 三方授权
justauth:
  enabled: true
  address: http://localhost:80
  type:
    qq:
      client-id: 10**********6
      client-secret: 1f7d08**********5b7**********29e
      redirect-uri: ${justauth.address}/social-callback?source=qq
      union-id: false
    weibo:
      client-id: 10**********6
      client-secret: 1f7d08**********5b7**********29e
      redirect-uri: ${justauth.address}/social-callback?source=weibo
    gitee:
      client-id: 914******************98
      client-secret: 02*****************ac
      redirect-uri: ${justauth.address}/social-callback?source=gitee
    dingtalk:
      client-id: 10**********6
      client-secret: 1f7d08**********5b7**********29e
      redirect-uri: ${justauth.address}/social-callback?source=dingtalk
    baidu:
      client-id: 10**********6
      client-secret: 1f7d08**********5b7**********29e
      redirect-uri: ${justauth.address}/social-callback?source=baidu
    csdn:
      client-id: 10**********6
      client-secret: 1f7d08**********5b7**********29e
      redirect-uri: ${justauth.address}/social-callback?source=csdn
    coding:
      client-id: 10**********6
      client-secret: 1f7d08**********5b7**********29e
      redirect-uri: ${justauth.address}/social-callback?source=coding
      coding-group-name: xx
    oschina:
      client-id: 10**********6
      client-secret: 1f7d08**********5b7**********29e
      redirect-uri: ${justauth.address}/social-callback?source=oschina
    alipay:
      client-id: 10**********6
      client-secret: 1f7d08**********5b7**********29e
      redirect-uri: ${justauth.address}/social-callback?source=alipay
      alipay-public-key: MIIB**************DAQAB
    wechat_open:
      client-id: 10**********6
      client-secret: 1f7d08**********5b7**********29e
      redirect-uri: ${justauth.address}/social-callback?source=wechat_open
    wechat_mp:
      client-id: 10**********6
      client-secret: 1f7d08**********5b7**********29e
      redirect-uri: ${justauth.address}/social-callback?source=wechat_mp
    wechat_enterprise:
      client-id: 10**********6
      client-secret: 1f7d08**********5b7**********29e
      redirect-uri: ${justauth.address}/social-callback?source=wechat_enterprise
      agent-id: 1000002
    gitlab:
      client-id: 10**********6
      client-secret: 1f7d08**********5b7**********29e
      redirect-uri: ${justauth.address}/social-callback?source=gitlab

配置config

package com.xie.common.social.config.properties;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * Social 配置属性
 *
 * @author thiszhc
 */
@Data
@Component
@ConfigurationProperties(prefix = "justauth")
public class SocialProperties {

    /**
     * 是否启用
     */
    private Boolean enabled;

    /**
     * 授权类型java
     */
    private Map<String, SocialLoginConfigProperties> type;

    /**
     * 授权过期时间
     */
    private Long timeout;

}

package com.xie.common.social.config.properties;

import lombok.Data;

/**
 * 社交登录配置
 *
 * @author thiszhc
 */
@Data
public class SocialLoginConfigProperties {

    /**
     * 应用 ID
     */
    private String clientId;

    /**
     * 应用密钥
     */
    private String clientSecret;

    /**
     * 回调地址
     */
    private String redirectUri;

    /**
     * 是否获取unionId
     */
    private boolean unionId;

    /**
     * Coding 企业名称
     */
    private String codingGroupName;

    /**
     * 支付宝公钥
     */
    private String alipayPublicKey;

    /**
     * 企业微信应用ID
     */
    private String agentId;

    /**
     * stackoverflow api key
     */
    private String stackOverflowKey;

    /**
     * 设备ID
     */java
    private String deviceId;

    /**
     * 客户端系统类型
     */
    private String clientOsType;

}

package com.xie.common.social.config;

import com.xie.common.social.config.properties.SocialProperties;
import com.xie.common.social.utils.AuthRedisStateCache;
import me.zhyd.oauth.cache.AuthStateCache;

import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;

/**
 * Social 配置属性
 * @author thiszhca
 */
@AutoConfiguration
@EnableConfigurationProperties(SocialProperties.class)
public class SocialConfig {

    @Bean
    public AuthStateCache authStateCache(SocialProperties socialProperties) {
        return new AuthRedisStateCache(socialProperties);
    }

}

package com.xie.common.social.utils;

import com.xie.common.redis.utils.RedisUtils;
import com.xie.common.social.config.properties.SocialProperties;
import lombok.AllArgsConstructor;
import me.zhyd.oauth.cache.AuthStateCache;


import java.time.Duration;

/**
 * 授权状态缓存
 */
@AllArgsConstructor
public class AuthRedisStateCache implements AuthStateCache {

    private final SocialProperties socialProperties;

    /**
     * 存入缓存
     *
     * @param key   缓存key
     * @param value 缓存内容
     */
    @Override
    public void cache(String key, String value) {
        RedisUtils.setCacheObject(key, value, Duration.ofMillis(socialProperties.getTimeout()));
    }

    /**
     * 存入缓存
     *
     * @param key     缓存key
     * @param value   缓存内容
     * @param timeout 指定缓存过期时间(毫秒)
     */
    @Override
    public void cache(String key, String value, long timeout) {
        RedisUtils.setCacheObject(key, value, Duration.ofMillis(timeout));
    }

    /**
     * 获取缓存内容
     *
     * @param key 缓存key
     * @return 缓存内容
     */
    @Override
    public String get(String key) {
        return RedisUtils.getCacheObject(key);
    }

    /**
     * 是否存在key,如果对应key的value值已过期,也返回false
     *
     * @param key 缓存key
     * @return true:存在key,并且value没过期;false:key不存在或者已过期
     */
    @Override
    public boolean containsKey(String key) {
        return RedisUtils.hasKey(key);
    }
}

登录流程

前端点击三方登录
// 绑定账号
export function authBinding(source: string) {
  return request({
    url: '/auth/binding/' + source,
    method: 'get'
  });
}
获取到地址传到前端
    @GetMapping("/binding/{source}")
    public R<String> authBinding(@PathVariable("source") String source) {
        SocialLoginConfigProperties obj = socialProperties.getType().get(source);
        if (ObjectUtil.isNull(obj)) {
            return R.fail(source + "平台账号暂不支持");
        }
        AuthRequest authRequest = SocialUtils.getAuthRequest(source, socialProperties);
        String authorizeUrl = authRequest.authorize(AuthStateUtils.createState());
        return R.ok("操作成功", authorizeUrl);
    }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8lg40IpY-1688890797374)(E:\java2\Templete\md\backend\image-20230709153652244.png)]

 authBinding(type).then((res: any) => {
    if (res.code === 200) {
      // 获取授权地址跳转
      window.location.href = res.data;
    } else {
      ElMessage.error(res.msg);
    }
在三方登录后进行回调
/**
 * 第三方登录
 */
export function callback(data: LoginData): AxiosPromise<any> {
  const LoginData = {
    ...data,
    clientId: clientId,
    grantType: 'social'
  };
  return request({
    url: '/auth/social/callback',
    method: 'post',
    data: LoginData
  });
}
    @PostMapping("/social/callback")
    public R<LoginVo> socialCallback(@RequestBody LoginBody loginBody) {
        // 获取第三方登录信息
        AuthResponse<AuthUser> response = SocialUtils.loginAuth(loginBody, socialProperties);
        AuthUser authUserData = response.getData();
        // 判断授权响应是否成功
        if (!response.ok()) {
            return R.fail(response.getMsg());
        }
        return loginService.sociaRegister(authUserData);
    }

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T3QwbJMq-1688890797375)(E:\java2\Templete\md\backend\image-20230709153749944.png)]

注册完成后插入sys_social表 就可以进行登录逻辑

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UgR9Ui20-1688890797377)(E:\java2\Templete\md\backend\image-20230709145800861.png)]

登录逻辑

前端点击登录
// 绑定账号
export function authBinding(source: string) {
  return request({
    url: '/auth/binding/' + source,
    method: 'get'
  });
}
获取到source和code

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GHLj6UKP-1688890797378)(E:\java2\Templete\md\backend\image-20230709154041468.png)]

进行登录

在这里插入图片描述

    @Override
    public LoginVo login(String clientId, LoginBody loginBody, SysClient client) {
        AuthResponse<AuthUser> authUserAuthResponse = SocialUtils.loginAuth(loginBody, socialProperties);
        if(!authUserAuthResponse.ok()){
            throw new ServiceException(authUserAuthResponse.getMsg());
        }
        AuthUser data = authUserAuthResponse.getData();
        String authId = data.getSource() + data.getUuid();
        SysSocialVo sysSocialVo = sysSocialService.selectByAuthId(authId);
        if(!ObjectUtil.isNotNull(sysSocialVo)){
            throw new ServiceException("你还没有绑定第三方账号,绑定后才可以登录!");
        }

        // 查找用户
        SysUserVo user = loadUser(sysSocialVo.getUserId());
        LoginUser loginUser = sysLoginService.buildLoginUser(user);
        SaLoginModel model = new SaLoginModel();
        model.setDevice(client.getDeviceType());
        // 自定义分配 不同用户体系 不同 token 授权时间 不设置默认走全局 yml 配置
        // 例如: 后台用户30分钟过期 app用户1天过期
        model.setTimeout(client.getTimeout());
        model.setActiveTimeout(client.getActiveTimeout());
        // 生成token
        LoginHelper.login(loginUser, model);
        LoginVo loginVo = new LoginVo();
        loginVo.setAccessToken(StpUtil.getTokenValue());
        return loginVo;

    }

前端回调逻辑

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WbH03zqy-1688890797381)(E:\java2\Templete\md\backend\image-20230709161810169.png)]

  if (!getToken()) {
    await loginByCode(data);
  } else {
    await callbackByCode(data);
  }

源码-RuoYi-Vue-Plus
模板代码

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值