1、新增依赖

<dependency>
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
<version>1.16.5</version>
</dependency>

2、前端示例

<template>
<div class="social-signup-container">
<div class="sign-btn" @click="thirdLoginClick('wechat')">
<span class="wx-svg-container"><svg-icon icon-class="wechat" class="icon"/></span>
微信
</div>
<div class="sign-btn" @click="thirdLoginClick('qq')">
<span class="qq-svg-container"><svg-icon icon-class="qq" class="icon"/></span>
QQ
</div>
<div class="sign-btn" @click="thirdLoginClick('gitee')">
<span class="gitee-svg-container"><svg-icon icon-class="gitee" class="icon"/></span>
Gitee
</div>
</div>
</template>
<script>
export default {
name: 'SocialSignin',
methods: {
   // 请求后台获取跳转路径
thirdLoginClick(source) {
this.$store.dispatch('user/thirdLogin', {source: source}).then(() => {
}).catch(() => {
})
}
}
}
</script>
  // 第三方登录
thirdLogin({commit}, userInfo) {
const {source} = userInfo
return new Promise((resolve, reject) => {
thirdLogin({source: source.trim()}).then(response => {
console.log("第三方登录返回", response)
if (response.data.code === "200") {
window.location.href = response.data.url
} else {
Message.warning(response.data.msg);
}
resolve()
}).catch(error => {
reject(error)
})
})
}
export function thirdLogin(data) {
return request({
url: '/login/render',
method: 'post',
params: {source: data.source}
})
}

3、后端示例

获取跳转路径
import com.mxy.common.core.utils.ServiceResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.request.AuthRequest;
import me.zhyd.oauth.utils.AuthStateUtils;
import org.springframework.web.bind.annotation.*; import javax.annotation.Resource;
import java.util.*; /**
* 第三方登录认证
*/
@RestController
@RequestMapping("/api/login")
@Api(value = "第三方登录相关接口", tags = {"第三方登录相关接口"})
@Slf4j
public class AuthRestApi { @Resource
private AuthUtil authUtil; @ApiOperation(value = "系统认证", notes = "系统认证")
@RequestMapping("/render")
public String renderAuth(String source) {
log.info("进入第三方认证:" + source);
Map<String, String> map = new HashMap<>();
AuthRequest authRequest = authUtil.getAuthRequest(source);
if (authRequest == null) {
map.put("code", "201");
map.put("msg", "系统未开启该登录方式");
return ServiceResult.success(map);
}
String token = AuthStateUtils.createState();
String authorizeUrl = authRequest.authorize(token);
log.info("获取返回url:" + authorizeUrl);
map.put("code", "200");
map.put("url", authorizeUrl);
return ServiceResult.success(map);
} }

拦截登录回调接口(ThirdPartyAuthenticationFilter)

import me.zhyd.oauth.model.AuthCallback;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; /**
* 第三方登录-拦截器
* 拼接入参
*/
public class ThirdPartyAuthenticationFilter extends AbstractAuthenticationProcessingFilter { public static String EXTEND_LOGIN_URL = "/api/login/callback/**"; private boolean getOnly = true; /**
* 表示这个 Filter 拦截 /api/login/callback/** 接口
*/
private static final AntPathRequestMatcher DEFAULT_ANT_PATH_REQUEST_MATCHER = new AntPathRequestMatcher(EXTEND_LOGIN_URL, "GET"); public ThirdPartyAuthenticationFilter() {
super(DEFAULT_ANT_PATH_REQUEST_MATCHER);
} @Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
if (this.getOnly && !"GET".equals(request.getMethod())) {
throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
} else {
ThirdPartyAuthenticationToken authRequest = new ThirdPartyAuthenticationToken(getSourceType(request), getCallback(request));
this.setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}
} protected void setDetails(HttpServletRequest request, ThirdPartyAuthenticationToken authRequest) {
authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request));
} /**
* 组装请求
*/
private AuthCallback getCallback(HttpServletRequest request) {
return AuthCallback.builder()
.code(request.getParameter("code"))
.auth_code(request.getParameter("auth_code"))
.authorization_code(request.getParameter("authorization_code"))
.oauth_token(request.getParameter("oauth_token"))
.state(request.getParameter("state"))
.oauth_verifier(request.getParameter("oauth_verifier"))
.build();
} /**
* 判断-登录系统类型
*/
private String getSourceType(HttpServletRequest request) {
String uri = request.getRequestURI();
int common = EXTEND_LOGIN_URL.length() - 2;
int start = uri.indexOf(EXTEND_LOGIN_URL.substring(0, common));
return uri.substring(start + common);
} }
封装用户信息(ThirdPartyAuthenticationToken)
import me.zhyd.oauth.model.AuthCallback;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority; import java.util.Collection; /**
* 模仿 UsernamePasswordAuthenticationToken
* 封装用户信息
*/
public class ThirdPartyAuthenticationToken extends AbstractAuthenticationToken { /**
* 认证返回
*/
private AuthCallback callback;
/**
* 登录类型
*/
private String source;
/**
* 用户实体
*/
private Object principal;
/**
* 用户id
*/
private Object credentials; public ThirdPartyAuthenticationToken(String source, AuthCallback callback) {
super(null);
this.source = source;
this.callback = callback;
setAuthenticated(false);
} public ThirdPartyAuthenticationToken(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities) {
super(authorities);
this.principal = principal;
this.credentials = credentials;
super.setAuthenticated(true);
} @Override
public Object getPrincipal() {
return principal;
} @Override
public Object getCredentials() {
return credentials;
} public Object getCallback() {
return callback;
} public Object getSource() {
return source;
}
}
第三方统一登录认证逻辑(ThirdPartyAuthenticationProvider)
package com.mxy.security.justauth;

import com.alibaba.fastjson.JSONObject;
import com.mxy.common.core.constant.Constants;
import com.mxy.common.core.entity.SelfUserEntity;
import com.mxy.common.core.entity.SysRole;
import com.mxy.common.core.entity.SysUser;
import com.mxy.common.core.entity.SysUserRole;
import com.mxy.common.core.utils.IPUtils;
import com.mxy.common.core.utils.RedisUtil;
import com.mxy.common.core.utils.ServletUtils;
import com.mxy.common.log.enums.OperType;
import com.mxy.security.security.service.SelfUserDetailsService;
import com.mxy.system.service.SysUserService;
import com.mxy.system.utils.LogUtil;
import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthRequest;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component; import javax.annotation.Resource;
import java.util.*; /**
* 第三方统一登录认证逻辑
*/
@Slf4j
@Component
public class ThirdPartyAuthenticationProvider implements AuthenticationProvider { @Autowired
private SelfUserDetailsService selfUserDetailsService;
@Autowired
private SysUserService sysUserService;
@Autowired
private RedisUtil redisUtil;
@Resource
private AuthUtil authUtil; @Resource
private BCryptPasswordEncoder bCryptPasswordEncoder; private Random random = new Random(); /**
* 第三方统一登录认证逻辑
*/
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
ThirdPartyAuthenticationToken token = (ThirdPartyAuthenticationToken) authentication;
String source = (String) token.getSource();
AuthCallback callback = (AuthCallback) token.getCallback();
log.info("------------进入" + source + "认证逻辑, callback params:" + JSONObject.toJSONString(callback));
AuthRequest authRequest = authUtil.getAuthRequest(source);
AuthResponse response = authRequest.login(callback);
if (response.getCode() == 5000) {
// 认证失败
throw new BadCredentialsException(source + "认证失败");
}
AuthUser authUser = (AuthUser) response.getData();
log.info("------------认证用户:{}", authUser);
// 根据 uuid 查询用户信息
SelfUserEntity userInfo = selfUserDetailsService.getUserInfoByUuid(authUser.getUuid());
if (userInfo == null) {
// 自动注册
userInfo = doRegister(authUser);
}
if (Constants.USER_STATE_TWO.equals(userInfo.getStatus())) {
LogUtil.saveLog("该账号已冻结[" + userInfo.getRelName() + "]", 99);
throw new LockedException("该账号已冻结");
}
// 角色集合
Set<GrantedAuthority> authorities = new HashSet<>();
// 查询用户角色
List<SysRole> sysRoleList = sysUserService.selectSysRoleByUserId(userInfo.getUserId());
for (SysRole sysRole : sysRoleList) {
authorities.add(new SimpleGrantedAuthority(sysRole.getRoleKey()));
}
userInfo.setAuthorities(authorities);
ThirdPartyAuthenticationToken authenticationResult = new ThirdPartyAuthenticationToken(userInfo, userInfo.getUserId(), userInfo.getAuthorities());
authenticationResult.setDetails(token.getDetails());
return authenticationResult;
} /**
* 账号注册
**/
public SelfUserEntity doRegister(AuthUser authUser) {
SelfUserEntity selfUser = new SelfUserEntity();
SysUser sysUser = new SysUser();
sysUser.setNickName(authUser.getNickname());
sysUser.setUsername(authUser.getSource() + (random.nextInt(89999999) + 10000000));
String password = String.valueOf(random.nextInt(899999) + 100000);
sysUser.setPassword(bCryptPasswordEncoder.encode(password));
sysUser.setAvatar(authUser.getAvatar());
sysUser.setRegistrationType(authUser.getSource());
sysUser.setUuid(authUser.getUuid());
sysUser.setLoginCount(0);
sysUser.setIpSource(IPUtils.getClientIp(Objects.requireNonNull(ServletUtils.getRequest())));
// 2-男
sysUser.setSex("2".equals(authUser.getRawUserInfo().getString("gender_type")) ? "0" : "1");
sysUser.setCreateUser("system");
sysUser.setRemark(authUser.getSource() + "首次注册默认密码为:" + password);
sysUser.setLoginDate(new Date());
sysUser.setUserType("2");
sysUser.insert(); // 新增用户角色关系
SysUserRole sysUserRole = new SysUserRole();
sysUserRole.setUserId(sysUser.getUserId());
// 游客
sysUserRole.setRoleId("2");
sysUserRole.insert();
BeanUtils.copyProperties(sysUser, selfUser);
selfUser.setRelName(sysUser.getNickName());
LogUtil.saveNoLoginLog("账号注册(" + authUser.getSource() + ")", JSONObject.toJSONString(sysUser), OperType.REGISTRATION.ordinal());
return selfUser;
} /**
* 判断是上面 authenticate 方法的 authentication 参数,是哪种类型
* Authentication 是个接口,实现类有很多,目前我们最熟悉的就是 ThirdPartyAuthenticationToken、UsernamePasswordAuthenticationToken
* 很明显,我们只支持 ThirdPartyAuthenticationToken,因为它封装的是TOKEN OPENID
*
* @param authentication
* @return
*/
@Override
public boolean supports(Class<?> authentication) {
return (ThirdPartyAuthenticationToken.class.isAssignableFrom(authentication));
}
}

工具类

import lombok.extern.slf4j.Slf4j;
import me.zhyd.oauth.config.AuthConfig;
import me.zhyd.oauth.request.AuthGiteeRequest;
import me.zhyd.oauth.request.AuthQqRequest;
import me.zhyd.oauth.request.AuthRequest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; @Slf4j
@Component
public class AuthUtil { @Value("${justauth.qq.clientId}")
private String qqClientId; @Value("${justauth.qq.clientSecret}")
private String qqClientSecret; @Value("${justauth.qq.redirectUri}")
private String qqRedirectUri; @Value("${justauth.gitee.clientId}")
private String giteeClientId; @Value("${justauth.gitee.clientSecret}")
private String giteeClientSecret; @Value("${justauth.gitee.redirectUri}")
private String giteeRedirectUri; /**
* 鉴权
*/
public AuthRequest getAuthRequest(String source) {
AuthRequest authRequest = null;
switch (source) {
case "qq":
authRequest = new AuthQqRequest(AuthConfig.builder()
.clientId(qqClientId)
.clientSecret(qqClientSecret)
.redirectUri(qqRedirectUri)
.build());
break;
case "gitee":
authRequest = new AuthGiteeRequest(AuthConfig.builder()
.clientId(giteeClientId)
.clientSecret(giteeClientSecret)
.redirectUri(giteeRedirectUri)
.build());
break;
default:
break;
}
return authRequest;
} }
# 第三方登录秘钥
justauth:
qq:
clientId: xxxxxxxxxx
clientSecret: xxxxxxxxxxxx
redirectUri: http://xxxxxxxxxx/api/login/callback/qq
gitee:
clientId: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
clientSecret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
redirectUri: http://xxxxxxxxxx/api/login/callback/gitee

JustAuth-第三方登录组件的更多相关文章

  1. 开源第三方登录组件OAuthLogin2.0 解析及开源地址

    OAuthLogin2.0介绍地址: 博客地址:http://www.cnblogs.com/dazhuangtage/p/6306133.html Nuget地址:https://www.nuget ...

  2. 开源第三方登录组件OAuthLogin2.0 架构解析及开源地址

    OAuthLogin2.0介绍地址: 入门地址:http://www.cnblogs.com/dazhuangtage/p/6306133.html Nuget地址:https://www.nuget ...

  3. 开源第三方登录组件OAuthLogin2.0 支持QQ,阿里巴巴,淘宝,京东,蘑菇街,有赞等平台

    Nuget地址:https://www.nuget.org/packages/OAuthLogin2.0/ 项目结构说明: AuthorizationProviders文件夹下主要存放内置的授权平台. ...

  4. SpringBoot + Layui + JustAuth +Mybatis-plus实现可第三方登录的简单后台管理系统

    1. 简介   在之前博客:SpringBoot基于JustAuth实现第三方授权登录 和 SpringBoot + Layui +Mybatis-plus实现简单后台管理系统(内置安全过滤器)上改造 ...

  5. 史上最全的整合第三方登录的工具JustAuth

    JustAuth,如你所见,它仅仅是一个第三方授权登录的工具类库,它可以让我们脱离繁琐的第三方登录SDK,让登录变得So easy! 参考图例 授权gitee 授权github 授权weibo 授权钉 ...

  6. .netcore 急速接入第三方登录,不看后悔

    新年新气象,趁着新年的喜庆,肝了十来天,终于发了第一版,希望大家喜欢. 如果有不喜欢看文字的童鞋,可以直接看下面的地址体验一下: https://oauthlogin.net/ 前言 此次带来得这个小 ...

  7. iOS - Share 分享/第三方登录

    1.系统方式创建分享 按照下图在 Info.plist 文件中将 Localization native development region 的值改为 China.如果不设置此项弹出的分享页面中显示 ...

  8. QQ第三方登录

    QQ第三方登录 在Android应用程序的开发过程中,很多时候需要加入用户登录/注册模块.除了自己动手设计登录界面并实现相应功能外,现在还可以借助百度.腾讯等开发者平台提供的第三方账号登录模块.最近研 ...

  9. sina第三方登录

    Sina  第三方登录 添加网站的流程如下: Sina接入主要审核点: • 1.网站可正常访问:若页面无法打开,或加载时间过长,或未建设完成的网站.或空白网站将无法通过审核: • 2.站点已部署微连接 ...

  10. UM_第三方登录

    参考官方文档(http://dev.umeng.com/social/ios/detail-share#7), 做出以下总结. 第三方登录主要用于简化用户登录流程,通过用户拥有的微博.QQ.微信等第三 ...

随机推荐

  1. Kubernetes(k8s)密码管理:Secret

    目录 一.系统环境 二.前言 三.Secret概览 四.Secret 的类型 五.各种类型的secret使用实例 5.1 创建kubernetes.io/service-account-token类型 ...

  2. Java-Integer好大一坑,一不小心就掉进去了

    遛马少年,一个代码写的很6的程序员,专注于技术干货分享 最近,在处理线上bug的时候,发现了一个奇怪的现象 业务代码大概是这样的 public static boolean doSth(Integer ...

  3. 【Oculus Interaction SDK】(六)实体按钮 && 按压交互

    前言 这篇文章是[Oculus Interaction SDK]系列的一部分,如果发现有对不上的对方,可以回去翻看我之前发布的文章,或在评论区留言.如果文章的内容已经不适用于新版本了,也可以直接联系我 ...

  4. 面向对象程序设计(二):C++模板初探

    背景:老师留了一个作业,对两个数组进行相加,但是总是会出现错误:首先我们需要知道当数组作为参数传递的时候是不能用 sizeof 的,因为当数组传入子函数就变成了普通的数组头:这时候使用 sizeof ...

  5. vscode环境配置(C/C++)

    一.MinGW和vscode的简单了解 1.MinGW是什么? MinGW(Minimalist GNU on Windows).它实际上是将经典的开源 C语言 编译器 GCC 移植到了 Window ...

  6. 【NOIP2017提高组正式赛】列队

    题解 本题的解法是丰富多彩的! 线段树做法是极好的 代码非常之少 一个很显然的想法是维护 \(n+1\) 颗线段树 那要怎么维护才能不爆空间呢? 我们发现尽管 \(n \times m\) 那么大 但 ...

  7. tensorflow读书笔记

    TensorFlow 是一个用于研究和生产的开放源代码机器学习库.TensorFlow 提供了各种 API,可供初学者和专家在桌面.移动.网络和云端环境下进行开发. TensorFlow是采用数据流图 ...

  8. 依那西普治疗多关节型和系统型JRA的长期疗效[EULAR2007_SAT0397]

    依那西普治疗多关节型和系统型JRA的长期疗效 Giannini EH, Ilowite NT. EULAR2007. Abstract No:SAT0397. 标签: EULAR2007,EULAR文 ...

  9. 病程极短(≤16周)的495例未分化关节炎患者随访2年的结局[EULAR2015_SAT0055]

    病程极短(≤16周)的495例未分化关节炎患者随访2年的结局   SAT0055 TWO-YEAR OUTCOME IN 495 PATIENTS WITH UNDIFFERENTIATED ARTH ...

  10. 3D模型在线查看工具

    3D场景工具推荐:NSDT场景编辑器. glTF Viewer 2.0是一个可以在线查看GLTF格式3D模型的,可以对模型进行显示设置.灯光设置来查看模型效果,除此之外还可以对模型进行性能分析和模型验 ...