您现在的位置: 首页 > 网站导航收录 > 百科知识百科知识
微信网页扫码登录((四十一)扩展JustAuth多租户微信扫码登录)
第三方,租户,绑定微信网页扫码登录((四十一)扩展JustAuth多租户微信扫码登录)
发布时间:2019-02-08加入收藏来源:互联网点击:
-
5. 所有的配置和绑定注册功能实现之后,我们还需要实现关键的一步,就是自定义实现OAuth2的第三方登录模式SocialTokenGranter,在第三方授权之后,通过此模式进行登录,自定义实现之后,记得t_oauth_client_details表需增加social授权。
SocialTokenGranter.java
/** * 第三方登录模式 * @author GitEgg */public class SocialTokenGranter extends AbstractTokenGranter { private static final String GRANT_TYPE = "social"; private final AuthenticationManager authenticationManager; private UserDetailsService userDetailsService; private IJustAuthFeign justAuthFeign; private RedisTemplate redisTemplate; private String captchaType; private String secretKey; private String secretKeySalt; public SocialTokenGranter(AuthenticationManager authenticationManager, AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, RedisTemplate redisTemplate, IJustAuthFeign justAuthFeign, UserDetailsService userDetailsService, String captchaType, String secretKey, String secretKeySalt) { this(authenticationManager, tokenServices, clientDetailsService, requestFactory, GRANT_TYPE); this.redisTemplate = redisTemplate; this.captchaType = captchaType; this.secretKey = secretKey; this.secretKeySalt = secretKeySalt; this.justAuthFeign = justAuthFeign; this.userDetailsService = userDetailsService; } protected SocialTokenGranter(AuthenticationManager authenticationManager, AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, String grantType) { super(tokenServices, clientDetailsService, requestFactory, grantType); this.authenticationManager = authenticationManager; } @Override protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) { Map<String, String> parameters = new LinkedHashMap<>(tokenRequest.getRequestParameters()); String socialKey = parameters.get(TokenConstant.SOCIAL_KEY); // Protect from downstream leaks of password parameters.remove(TokenConstant.SOCIAL_KEY); // 校验socialId String socialId; try { // 将socialId进行加密返回 DES des = new DES(Mode.CTS, Padding.PKCS5Padding, secretKey.getBytes(), secretKeySalt.getBytes()); String desSocialKey = des.decryptStr(socialKey); // 获取缓存中的key socialId = (String) redisTemplate.opsForValue().get(AuthConstant.SOCIAL_VALIDATION_PREFIX desSocialKey); } catch (Exception e) { throw new InvalidGrantException("第三方登录验证已失效,请返回登录页重新操作"); } if (StringUtils.isEmpty(socialId)) { throw new InvalidGrantException("第三方登录验证已失效,请返回登录页重新操作"); } // 校验userId String userId; try { Result<Object> socialResult = justAuthFeign.userBindQuery(Long.parseLong(socialId)); if (null == socialResult || StringUtils.isEmpty(socialResult.getData())) { throw new InvalidGrantException("操作失败,请返回登录页重新操作"); } userId = (String) socialResult.getData(); } catch (Exception e) { throw new InvalidGrantException("操作失败,请返回登录页重新操作"); } if (StringUtils.isEmpty(userId)) { throw new InvalidGrantException("操作失败,请返回登录页重新操作"); } // 这里是通过用户id查询用户信息 UserDetails userDetails = this.userDetailsService.loadUserByUsername(userId); Authentication userAuth = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); ((AbstractAuthenticationToken)userAuth).setDetails(parameters); OAuth2Request storedOAuth2Request = getRequestFactory().createOAuth2Request(client, tokenRequest); return new OAuth2Authentication(storedOAuth2Request, userAuth); }}
6. 后台处理完成之后,前端VUE也需要做回调处理
因为是前后端分离的项目,我们这里需要将第三方回调接口配置在vue页面,前端页面根据账户信息判断是直接登录还是进行绑定或者注册等操作。新建SocialCallback.vue用于处理前端第三方登录授权后的回调操作。
SocialCallback.vue
<template> <div> </div></template><script>import { socialLoginCallback } from '@/api/login'import { mapActions } from 'vuex'export default { name: 'SocialCallback', created () { this.$loading.show({ tip: '登录中......' }) const query = this.$route.query const socialType = this.$route.params.socialType this.socialCallback(socialType, query) }, methods: { ...mapActions(['Login']), getUrlKey: function (name) { // eslint-disable-next-line no-sparse-arrays return decodeURIComponent((new RegExp('[?|&]' name '=' '([^&;] ?)(&|#|;|$)').exec(window.opener.location.href) || [, ''])[1].replace(/ /g, ' ')) || null }, socialCallback (socialType, parameter) { const that = this socialLoginCallback(socialType, parameter).then(res => { that.$loading.hide() const bindResult = res.data if (bindResult && bindResult !== '') { if (bindResult.success && bindResult.data) { // 授权后发现已绑定,那么直接调用第三方登录 this.socialLogin(bindResult.data) } else if (bindResult.code === 601) { // 授权后没有绑定则跳转到绑定界面 that.$router.push({ name: 'socialBind', query: { redirect: this.getUrlKey('redirect'), key: bindResult.data } }) } else if (bindResult.code === 602) { // 该账号已绑定多个账号,请联系系统管理员,或者到个人中心解绑 this.$notification['error']({ message: '错误', description: ((res.response || {}).data || {}).message || '该账号已绑定多个账号,请联系系统管理员,或者到个人中心解绑', duration: 4 }) } else { // 提示获取第三方登录失败 this.$notification['error']({ message: '错误', description: '第三方登录失败,请稍后再试', duration: 4 }) } } else { // 提示获取第三方登录失败 this.$notification['error']({ message: '错误', description: '第三方登录失败,请稍后再试', duration: 4 }) } }) }, // 第三方登录后回调 socialLogin (key) { const { Login } = this // 执行登录操作 const loginParams = { grant_type: 'social', social_key: key } this.$loading.show({ tip: '登录中......' }) Login(loginParams) .then((res) => this.loginSuccess(res)) .catch(err => this.loginError(err)) .finally(() => { this.$loading.hide() if (this.getUrlKey('redirect')) { window.opener.location.href = window.opener.location.origin this.getUrlKey('redirect') } else { window.opener.location.reload() } window.close() }) }, loginSuccess (res) { this.$notification['success']({ message: '提示', description: '第三方登录成功', duration: 4 }) }, loginError (err) { this.$notification['error']({ message: '错误', description: ((err.response || {}).data || {}).message || '请求出现错误,请稍后再试', duration: 4 }) } }}</script><style></style>
下一篇:返回列表
相关链接 |
||
网友回复(共有 0 条回复) |