马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
注:本文基于 若依 集成just-auth实现第三方授权登录 修改美满,全部步调仅代表本人如下环境亲测可用,其他环境需自辩或联系查看缘故原由!
体系环境
运行体系:Windows10专业版、Linux Centos7.6
Java 版本:1.8.0_371
node 版本:14.21.3
Mysql版本:5.5.39、5.7.44
一、后台设置
1、添加依赖
- <!-- JustAuth第三方授权登录 -->
- <dependency>
- <groupId>me.zhyd.oauth</groupId>
- <artifactId>JustAuth</artifactId>
- <version>1.15.6</version>
- </dependency>
- <!-- HttpClient -->
- <dependency>
- <groupId>org.apache.httpcomponents</groupId>
- <artifactId>httpclient</artifactId>
- </dependency>
复制代码 2、添加认证授权工具类
- package top.chengrongyu.common.utils;
- import me.zhyd.oauth.cache.AuthStateCache;
- import me.zhyd.oauth.config.AuthConfig;
- import me.zhyd.oauth.exception.AuthException;
- import me.zhyd.oauth.request.*;
- /**
- * 认证授权工具类
- *
- * @author ruoyi
- */
- public class AuthUtils
- {
- @SuppressWarnings("deprecation")
- public static AuthRequest getAuthRequest(String source, String clientId, String clientSecret, String redirectUri,
- AuthStateCache authStateCache)
- {
- AuthRequest authRequest = null;
- switch (source.toLowerCase())
- {
- case "dingtalk":
- authRequest = new AuthDingTalkRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
- .redirectUri(redirectUri).build(), authStateCache);
- break;
- case "baidu":
- authRequest = new AuthBaiduRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
- .redirectUri(redirectUri).build(), authStateCache);
- break;
- case "github":
- authRequest = new AuthGithubRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
- .redirectUri(redirectUri).build(), authStateCache);
- break;
- case "gitee":
- authRequest = new AuthGiteeRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
- .redirectUri(redirectUri).build(), authStateCache);
- break;
- case "weibo":
- authRequest = new AuthWeiboRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
- .redirectUri(redirectUri).build(), authStateCache);
- break;
- case "coding":
- authRequest = new AuthCodingRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
- .redirectUri(redirectUri).codingGroupName("").build(), authStateCache);
- break;
- case "oschina":
- authRequest = new AuthOschinaRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
- .redirectUri(redirectUri).build(), authStateCache);
- break;
- case "alipay":
- // 支付宝在创建回调地址时,不允许使用localhost或者127.0.0.1,所以这儿的回调地址使用的局域网内的ip
- authRequest = new AuthAlipayRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
- .alipayPublicKey("").redirectUri(redirectUri).build(), authStateCache);
- break;
- case "qq":
- authRequest = new AuthQqRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
- .redirectUri(redirectUri).build(), authStateCache);
- break;
- case "wechat_open":
- authRequest = new AuthWeChatOpenRequest(AuthConfig.builder().clientId(clientId)
- .clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);
- break;
- case "csdn":
- authRequest = new AuthCsdnRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
- .redirectUri(redirectUri).build(), authStateCache);
- break;
- case "taobao":
- authRequest = new AuthTaobaoRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
- .redirectUri(redirectUri).build(), authStateCache);
- break;
- case "douyin":
- authRequest = new AuthDouyinRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
- .redirectUri(redirectUri).build(), authStateCache);
- break;
- case "linkedin":
- authRequest = new AuthLinkedinRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
- .redirectUri(redirectUri).build(), authStateCache);
- break;
- case "microsoft":
- authRequest = new AuthMicrosoftRequest(AuthConfig.builder().clientId(clientId)
- .clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);
- break;
- case "mi":
- authRequest = new AuthMiRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
- .redirectUri(redirectUri).build(), authStateCache);
- break;
- case "toutiao":
- authRequest = new AuthToutiaoRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
- .redirectUri(redirectUri).build(), authStateCache);
- break;
- case "teambition":
- authRequest = new AuthTeambitionRequest(AuthConfig.builder().clientId(clientId)
- .clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);
- break;
- case "pinterest":
- authRequest = new AuthPinterestRequest(AuthConfig.builder().clientId(clientId)
- .clientSecret(clientSecret).redirectUri(redirectUri).build(), authStateCache);
- break;
- case "renren":
- authRequest = new AuthRenrenRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
- .redirectUri(redirectUri).build(), authStateCache);
- break;
- case "stack_overflow":
- authRequest = new AuthStackOverflowRequest(AuthConfig.builder().clientId(clientId)
- .clientSecret(clientSecret).redirectUri(redirectUri).stackOverflowKey("").build(),
- authStateCache);
- break;
- case "huawei":
- authRequest = new AuthHuaweiRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
- .redirectUri(redirectUri).build(), authStateCache);
- break;
- case "wechat_enterprise":
- authRequest = new AuthWeChatEnterpriseRequest(AuthConfig.builder().clientId(clientId)
- .clientSecret(clientSecret).redirectUri(redirectUri).agentId("").build(), authStateCache);
- break;
- case "kujiale":
- authRequest = new AuthKujialeRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
- .redirectUri(redirectUri).build(), authStateCache);
- break;
- case "gitlab":
- authRequest = new AuthGitlabRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
- .redirectUri(redirectUri).build(), authStateCache);
- break;
- case "meituan":
- authRequest = new AuthMeituanRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
- .redirectUri(redirectUri).build(), authStateCache);
- break;
- case "eleme":
- authRequest = new AuthElemeRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
- .redirectUri(redirectUri).build());
- break;
- case "wechat_mp":
- authRequest = new AuthWeChatMpRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
- .redirectUri(redirectUri).build(), authStateCache);
- break;
- case "aliyun":
- authRequest = new AuthAliyunRequest(AuthConfig.builder().clientId(clientId).clientSecret(clientSecret)
- .redirectUri(redirectUri).build(), authStateCache);
- break;
- default:
- break;
- }
- if (null == authRequest)
- {
- throw new AuthException("未获取到有效的Auth配置");
- }
- return authRequest;
- }
- }
复制代码 3、新建第三方登录授权表
- -- ----------------------------
- -- 第三方授权表
- -- ----------------------------
- create table sys_auth_user (
- auth_id bigint(20) not null auto_increment comment '授权ID',
- uuid varchar(500) not null comment '第三方平台用户唯一ID',
- user_id bigint(20) not null comment '系统用户ID',
- login_name varchar(30) not null comment '登录账号',
- user_name varchar(30) default '' comment '用户昵称',
- avatar varchar(500) default '' comment '头像地址',
- email varchar(255) default '' comment '用户邮箱',
- source varchar(255) default '' comment '用户来源',
- create_time datetime comment '创建时间',
- primary key (auth_id)
- ) engine=innodb auto_increment=100 comment = '第三方授权表';
复制代码 4、添加实体表、Mapper、Service接口类
(1)实体
- package top.chengrongyu.system.domain;
- import lombok.Data;
- import top.chengrongyu.common.core.domain.BaseEntity;
- /**
- * 第三方授权表 sys_auth_user
- *
- * @author ruoyi
- */
- @Data
- public class SysAuthUser extends BaseEntity
- {
- private static final long serialVersionUID = 1L;
- /** 授权ID */
- private Long authId;
- /** 第三方平台用户唯一ID */
- private String uuid;
- /** 系统用户ID */
- private Long userId;
- /** 登录账号 */
- private String userName;
- /** 用户昵称 */
- private String nickName;
- /** 头像地址 */
- private String avatar;
- /** 用户邮箱 */
- private String email;
- /** 用户来源 */
- private String source;
- }
复制代码 (2)在原user的Mapper下添加如下接口
- /**
- * 根据用户编号查询授权列表
- *
- * @param userId 用户编号
- * @return 授权列表
- */
- public List<SysAuthUser> selectAuthUserListByUserId(Long userId);
-
- /**
- * 根据uuid查询用户信息
- *
- * @param uuid 唯一信息
- * @return 结果
- */
- public SysUser selectAuthUserByUuid(String uuid);
-
- /**
- * 校验source平台是否绑定
- *
- * @param userId 用户编号
- * @param source 绑定平台
- * @return 结果
- */
- public int checkAuthUser(@Param("userId") Long userId, @Param("source") String source);
- /**
- * 新增第三方授权信息
- *
- * @param authUser 用户信息
- * @return 结果
- */
- public int insertAuthUser(SysAuthUser authUser);
- /**
- * 根据编号删除第三方授权信息
- *
- * @param authId 授权编号
- * @return 结果
- */
- public int deleteAuthUser(Long authId);
复制代码 (3)在原user的Service下添加如下接口
- /**
- * 根据用户编号查询授权列表
- *
- * @param userId 用户编号
- * @return 授权列表
- */
- public List<SysAuthUser> selectAuthUserListByUserId(Long userId);
复制代码 (4)在原user的ServiceImpl下添加如下接口
- /**
- * 根据用户编号查询授权列表
- *
- * @param userId 用户编号
- * @return 授权列表
- */
- public List<SysAuthUser> selectAuthUserListByUserId(Long userId)
- {
- return userMapper.selectAuthUserListByUserId(userId);
- }
复制代码 (5)在原user的Mapper.xml下添加如下sql
- <resultMap id="SysAuthUserResult" type="SysAuthUser">
- <id property="authId" column="auth_id" />
- <result property="uuid" column="uuid" />
- <result property="userId" column="user_id" />
- <result property="userName" column="user_name" />
- <result property="nickName" column="nick_name" />
- <result property="avatar" column="avatar" />
- <result property="email" column="email" />
- <result property="source" column="source" />
- <result property="createTime" column="create_time" />
- </resultMap>
- <select id="selectAuthUserByUuid" parameterType="String" resultMap="SysUserResult">
- select b.user_id as user_id, b.user_name as user_name, b.password as password
- from sys_auth_user a left join sys_user b on a.user_id = b.user_id
- where a.uuid = #{uuid} and b.del_flag = '0'
- </select>
-
- <select id="selectAuthUserListByUserId" parameterType="Long" resultMap="SysAuthUserResult">
- select auth_id, uuid, user_id, user_name, nick_name, avatar, email, source, create_time
- from sys_auth_user where user_id = #{userId}
- </select>
-
- <select id="checkAuthUser" parameterType="SysAuthUser" resultType="int">
- select count(1) from sys_auth_user where user_id=#{userId} and source=#{source} limit 1
- </select>
-
- <insert id="insertAuthUser" parameterType="SysAuthUser">
- insert into sys_auth_user(
- <if test="uuid != null and uuid != ''">uuid,</if>
- <if test="userId != null and userId != 0">user_id,</if>
- <if test="userName != null and userName != ''">user_name,</if>
- <if test="nickName != null and nickName != ''">nick_name,</if>
- <if test="avatar != null and avatar != ''">avatar,</if>
- <if test="email != null and email != ''">email,</if>
- <if test="source != null and source != ''">source,</if>
- create_time
- )values(
- <if test="uuid != null and uuid != ''">#{uuid},</if>
- <if test="userId != null and userId != 0">#{userId},</if>
- <if test="userName != null and userName != ''">#{userName},</if>
- <if test="nickName != null and nickName != ''">#{nickName},</if>
- <if test="avatar != null and avatar != ''">#{avatar},</if>
- <if test="email != null and email != ''">#{email},</if>
- <if test="source != null and source != ''">#{source},</if>
- sysdate()
- )
- </insert>
-
- <delete id="deleteAuthUser" parameterType="Long">
- delete from sys_auth_user where auth_id = #{authId}
- </delete>
复制代码 5、添加SysAuthController
注意:
①这里的auths下的clientId需要自己获取正式的个人网站客户端id、密钥、回调 等信息;
②回调地址需要写成前端页面的地址,不是后端的;
③此处更改了三方登录的方式,新增了无绑定账户自动创建账户并登录的代码逻辑,并修复了一些绑定三方账户的bug;
参考JustAuth官网集成第三方步调
- package top.chengrongyu.web.controller.system;
- import java.io.IOException;
- import java.util.HashMap;
- import java.util.Map;
- import javax.servlet.http.HttpServletRequest;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.DeleteMapping;
- import org.springframework.web.bind.annotation.GetMapping;
- import org.springframework.web.bind.annotation.PathVariable;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.ResponseBody;
- import org.springframework.web.bind.annotation.RestController;
- import com.alibaba.fastjson2.JSONObject;
- import me.zhyd.oauth.cache.AuthDefaultStateCache;
- import me.zhyd.oauth.cache.AuthStateCache;
- 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 me.zhyd.oauth.utils.AuthStateUtils;
- import org.springframework.web.multipart.MultipartFile;
- import top.chengrongyu.common.constant.Constants;
- import top.chengrongyu.common.core.controller.BaseController;
- import top.chengrongyu.common.core.domain.AjaxResult;
- import top.chengrongyu.common.core.domain.entity.SysUser;
- import top.chengrongyu.common.core.domain.model.LoginUser;
- import top.chengrongyu.common.enums.UserStatus;
- import top.chengrongyu.common.exception.ServiceException;
- import top.chengrongyu.common.utils.AuthUtils;
- import top.chengrongyu.common.utils.SecurityUtils;
- import top.chengrongyu.common.utils.StringUtils;
- import top.chengrongyu.framework.web.service.SysLoginService;
- import top.chengrongyu.framework.web.service.SysPermissionService;
- import top.chengrongyu.framework.web.service.TokenService;
- import top.chengrongyu.system.domain.SysAuthUser;
- import top.chengrongyu.system.mapper.SysUserMapper;
- import top.chengrongyu.system.service.ISysUserService;
- import static top.chengrongyu.common.utils.file.FileUploadUtils.fileUrlConvertToMultipartImage;
- import static top.chengrongyu.common.utils.file.FileUploadUtils.upload;
- /**
- * 第三方认证授权处理
- *
- * @author cry
- */
- @RestController
- @RequestMapping("/system/auth")
- public class SysAuthController extends BaseController {
- private AuthStateCache authStateCache;
- @Autowired
- private ISysUserService userService;
- @Autowired
- private SysPermissionService permissionService;
- @Autowired
- private TokenService tokenService;
- @Autowired
- private SysUserMapper userMapper;
- @Autowired
- private SysLoginService loginService;
- /**
- * 三方应用登录回调地址
- */
- String redirectUri = "http://127.0.0.1:81/social-login?source=";// PC
- String redirectUriMobile = "http://127.0.0.1:9090/pages/socialLogin?source=";// Mobile 注意:/# 哈希值不能携带!URL中的哈希值(#)部分可能不会被服务器处理
- /**
- * gitee 客户端ID
- */
- String giteeClientId = "xxxx";
- /**
- * gitee 客户端密钥
- */
- String giteeClientSecret = "xxxx";
- private final static Map<String, String> auths = new HashMap<String, String>();
- {
- auths.put("gitee", "{"clientId":"" + giteeClientId + "","clientSecret":"" + giteeClientSecret + "","redirectUri":"" + redirectUri + "gitee"+"","redirectUriMobile":"" + redirectUriMobile + "gitee"}");
- authStateCache = AuthDefaultStateCache.INSTANCE;
- }
- /**
- * 认证授权
- *
- * @param source 三方平台
- * @param type 请求端类型 PC、Mobile
- * @throws IOException
- */
- @GetMapping("/binding/{source}/{type}")
- @ResponseBody
- public AjaxResult authBinding(@PathVariable("source") String source,@PathVariable("type")String type, HttpServletRequest request) throws IOException {
- LoginUser tokenUser = tokenService.getLoginUser(request);
- if (StringUtils.isNotNull(tokenUser) && userMapper.checkAuthUser(tokenUser.getUserId(), source) > 0) {
- return error(source + "平台账号已经绑定");
- }
- String obj = auths.get(source);
- if (StringUtils.isEmpty(obj)) {
- return error(source + "平台账号暂不支持");
- }
- JSONObject json = JSONObject.parseObject(obj);
- /**
- * 校验是PC端还是Mobile端
- */
- String url = "PC".equals(type) ? json.getString("redirectUri") : json.getString("redirectUriMobile");
- AuthRequest authRequest = AuthUtils.getAuthRequest(source, json.getString("clientId"), json.getString("clientSecret"), url, authStateCache);
- String authorizeUrl = authRequest.authorize(AuthStateUtils.createState());
- System.out.println(authorizeUrl);
- return success(authorizeUrl);
- }
- @SuppressWarnings("unchecked")
- @GetMapping("/social-login/{source}/{type}")
- public AjaxResult socialLogin(@PathVariable("source") String source,@PathVariable("type") String type, AuthCallback callback, HttpServletRequest request) throws IOException {
- String obj = auths.get(source);
- if (StringUtils.isEmpty(obj)) {
- return AjaxResult.error(10002, "第三方平台系统不支持或未提供来源");
- }
- JSONObject json = JSONObject.parseObject(obj);
- /**
- * 校验是PC端还是Mobile端
- */
- String url = "PC".equals(type) ? json.getString("redirectUri") : json.getString("redirectUriMobile");
- AuthRequest authRequest = AuthUtils.getAuthRequest(source, json.getString("clientId"), json.getString("clientSecret"), url, authStateCache);
- AuthResponse<AuthUser> response = authRequest.login(callback);
- if (response.ok()) {
- /**
- * 获取当前请求下登录用户缓存信息
- */
- LoginUser tokenUser = null;
- try {
- tokenUser = tokenService.getLoginUser(request);
- } catch (ServiceException e) {
- /**
- * 提示获取用户信息异常时,抛出异常 不做处理
- */
- throw e;
- }finally {
- /**
- * 根据三方登录平台的uuid查询用户三方绑定信息
- */
- SysUser authUserByUuid = userMapper.selectAuthUserByUuid(source + response.getData().getUuid());
- /**
- * 验证当前用户是否已经登录 并且验证当前登录的和绑定的是否是一个账户
- */
- if (StringUtils.isNotNull(tokenUser)) {
- if (StringUtils.isNotNull(authUserByUuid) && tokenUser.getUserId() == authUserByUuid.getUserId()) {
- String token = tokenService.createToken(SecurityUtils.getLoginUser());
- return success().put(Constants.TOKEN, token);
- }
- /**
- * 判断 当前登录的和绑定的不是一个账户时
- */
- if (authUserByUuid != null && authUserByUuid.getUserId() != null) {
- return AjaxResult.error(10002, "对不起,来自" + source + "的账户已有绑定账户,如有需要,请登录原账户解绑后重新绑定!");
- }else{
- /**
- * 若已经登录,但未绑定该三方授权信息
- * 则直接绑定当前登录的系统账号
- */
- SysAuthUser authUser = new SysAuthUser();
- authUser.setAvatar(response.getData().getAvatar());
- authUser.setUuid(source + response.getData().getUuid());
- authUser.setUserId(SecurityUtils.getUserId());
- authUser.setUserName(response.getData().getUsername());
- authUser.setNickName(response.getData().getNickname());
- authUser.setEmail(response.getData().getEmail());
- authUser.setSource(source);
- userMapper.insertAuthUser(authUser);
- String token = tokenService.createToken(SecurityUtils.getLoginUser());
- return success().put(Constants.TOKEN, token);
- }
- }
- /**
- * 当用户未登录
- * 判断 根据三方登录平台的uuid查询用户三方绑定信息 不为空时
- */
- if (StringUtils.isNotNull(authUserByUuid)) {
- SysUser user = userService.selectUserByUserName(authUserByUuid.getUserName());
- if (StringUtils.isNull(user)) {
- throw new ServiceException("登录用户:" + user.getUserName() + " 不存在");
- } else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) {
- throw new ServiceException("对不起,您的账号:" + user.getUserName() + " 已被删除");
- } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) {
- throw new ServiceException("对不起,您的账号:" + user.getUserName() + " 已停用");
- }
- LoginUser loginUser = new LoginUser(user.getUserId(), user.getDeptId(), user, permissionService.getMenuPermission(user));
- String token = tokenService.createToken(loginUser);
- return success().put(Constants.TOKEN, token);
- } else {
- /**
- * 当用户未登录 且
- * 该三方登录信息也未绑定用户时
- * 创建一个新用户进行绑定
- */
- SysUser user = new SysUser();
- /**
- * 默认用户名为 uuid + _三方平台名称
- */
- user.setUserName(response.getData().getUuid()+"_"+source);
- /**
- * 默认密码为 123456
- */
- user.setPassword(SecurityUtils.encryptPassword("123456"));
- user.setNickName(response.getData().getNickname());
- /**
- * 由于存储文件路径以用户为单位
- * 所以需要登录后跟俊网络地址修改用户头像
- */
- MultipartFile multipartFile = fileUrlConvertToMultipartImage(response.getData().getAvatar(),user.getUserName()+"_avatar.png");
- String avatarUrl = upload(multipartFile);
- user.setAvatar(avatarUrl);
- user.setEmail(response.getData().getEmail());
- user.setRemark(response.getData().getRemark());
- /**
- * 新增用户信息
- */
- int rows = userService.insertUser(user);
- if(rows>0){
- /**
- * 用户添加成功后 绑定该三方授权信息
- */
- SysAuthUser authUser = new SysAuthUser();
- authUser.setUuid(source + response.getData().getUuid());
- authUser.setUserId(user.getUserId());
- authUser.setAvatar(response.getData().getAvatar());
- authUser.setUserName(response.getData().getUsername());
- authUser.setNickName(response.getData().getNickname());
- authUser.setEmail(response.getData().getEmail());
- authUser.setSource(source);
- userMapper.insertAuthUser(authUser);
- // 登录并生成令牌
- String token = loginService.login(user.getUserName(), "123456", "","");
- return success().put(Constants.TOKEN, token);
- }
- }
- }
- }
- return AjaxResult.error(10002, "对不起,授权信息验证不通过,请联系管理员");
- }
- /**
- * 取消授权
- */
- @DeleteMapping(value = "/unlock/{authId}")
- public AjaxResult unlockAuth(@PathVariable Long authId) {
- return toAjax(userMapper.deleteAuthUser(authId));
- }
- }
复制代码 6、在SysProfileController获取用户个人信息的profile方法中添加如下行
使在查询的同时携带用户的三方登录授权信息
- ajax.put("auths", userService.selectAuthUserListByUserId(user.getUserId()));
复制代码 二、前台设置(Vue、Uniapp 设置方法一致)
1、在校验文件permission.js中添加白名单
2、在/api/system 中添加授权绑定、解除账号接口文件auth.js
auth.js
- import request from '@/utils/request'
- // 绑定账号
- export function authBinding(source) {
- return request({
- url: '/system/auth/binding/' + source + '/PC', //PC、Mobile 写死即可
- method: 'get'
- })
- }
- // 解绑账号
- export function authUnlock(authId) {
- return request({
- url: '/system/auth/unlock/' + authId,
- method: 'delete'
- })
- }
复制代码 3、在login.js中添加三方登录接口
- // 第三方平台登录
- export function socialLogin(source, code, state) {
- const data = {
- code,
- state
- }
- return request({
- url: '/system/auth/social-login/' + source + '/PC', //PC、Mobile 写死即可
- method: 'get',
- params: data
- })
- }
复制代码 4、设置route文件夹下的index.js路由信息(Uniapp无该步调)
在公共路由 constantRoutes 中添加三方登录的页面路径,使其在未登录时可以正常跳转页面
- { path: '/social-login',
- component: () => import('@/views/socialLogin'), hidden: true },
复制代码 5、设置store/modules文件夹下的user.js用户存储信息
添加action下的函数
- // 第三方平台登录
- SocialLogin({ commit }, userInfo) {
- const code = userInfo.code
- const state = userInfo.state
- const source = userInfo.source
- return new Promise((resolve, reject) => {
- socialLogin(source, code, state).then(res => {
- setToken(res.token)
- commit('SET_TOKEN', res.token)
- resolve()
- }).catch(error => {
- reject(error)
- })
- })
- },
复制代码 6、设置utils文件夹下的request.js请求文件处理信息
添加第三方登录失败时的报错信息处理,夹在401和500之间即可
- else if (code === 10002) {
- // 第三方登录错误提示
- MessageBox.confirm(msg, '系统提示', {
- confirmButtonText: '重新登录',
- cancelButtonText: '取消',
- type: 'warning'
- }
- ).then(() => {
- store.dispatch('LogOut').then(() => {
- location.href = '/index';// Uniapp 写 '/pages/login'
- })
- }).catch(() => { });
- return Promise.reject(new Error(msg))
- }
复制代码 7、添加三方登录页面socialLogin.vue
socialLogin.vue
- <template>
- <div></div>
- </template>
-
- <script>
- import { Loading } from 'element-ui'
- let loadingInstance;
- export default {
- data() {
- return {
- redirect: undefined,
- };
- },
- created() {
- loadingInstance = Loading.service({
- lock: true,
- text: "正在验证第三方应用账户数据,请稍候",
- spinner: "el-icon-loading",
- background: "rgba(0, 0, 0, 0.7)",
- })
- // 第三方登录回调参数
- this.source = this.$route.query.source;
- this.code = this.$route.query.code;
- this.state = this.$route.query.state;
- this.$store.dispatch("SocialLogin", {
- code: this.code,
- state: this.state,
- source: this.source
- }).then(() => {
- loadingInstance.close();
- this.$router.push({ path: this.redirect || "/" }).catch(()=>{});
- }).catch(() => {
- loadingInstance.close();
- });
- },
- methods: {
- },
- };
- </script>
-
- <style rel="stylesheet/scss" lang="scss">
- </style>
复制代码 8、登录页面添加三方登录跳转信息链接
vue
- <!-- 第三方应用登录 -->
- <el-form-item style="width:100%;">
- <div class="oauth-login" style="display:flex">
- <div class="oauth-login-item" @click="doSocialLogin('gitee')">
- <svg-icon icon-class="gitee" style="height:1.2em" />
- <span>Gitee</span>
- </div>
- <div class="oauth-login-item" @click="doSocialLogin('github')">
- <svg-icon icon-class="github" style="height:1.2em" />
- <span>Github</span>
- </div>
- <div class="oauth-login-item">
- <svg-icon icon-class="weixin" style="height:1.2em" />
- <span>Weixin</span>
- </div>
- <div class="oauth-login-item">
- <svg-icon icon-class="qq" style="height:1.2em" />
- <span>QQ</span>
- </div>
- </div>
- </el-form-item>
复制代码 js函数
- import { authBinding } from "@/api/system/auth";
-
- ……
-
- // 三方登录
- doSocialLogin(source) {
- authBinding(source).then(res => {
- top.location.href = res.msg;
- });
- }
- ……
复制代码 css
- .oauth-login {
- display: flex;
- align-items: cen;
- cursor:pointer;
- }
- .oauth-login-item {
- display: flex;
- align-items: center;
- margin-right: 10px;
- }
- .oauth-login-item img {
- height: 25px;
- width: 25px;
- }
- .oauth-login-item span:hover {
- text-decoration: underline red;
- color: red;
- }
复制代码 9、添加个人中心三方登录信息展示(Uniapp需根据需要自界说)
views\system\user\profile\index.vue添加如下
vue
- <el-tab-pane label="第三方应用" name="thirdParty">
- <thirdParty :auths="auths" />
- </el-tab-pane>
复制代码 js
- import thirdParty from "./thirdParty";
- export default {
- name: "Profile",
- components: { userAvatar, userInfo, resetPwd, thirdParty },
- ……
- auths: {},
- ……
- /**
- * 赋值 用户授权三方登录信息 用于回显socialLogin页面
- */
- this.auths = response.auths;
复制代码 添加thirdParty.vue页面
- <template>
- <div>
- <el-table :data="auths" style="width: 100%; height: 100%; font-size: 10px">
- <el-table-column label="序号" width="50" type="index"></el-table-column>
- <el-table-column
- label="绑定账号平台"
- width="140"
- align="center"
- prop="source"
- :show-overflow-tooltip="true"
- />
- <el-table-column label="头像" width="120" align="center" prop="avatar">
- <template slot-scope="scope">
- <image-preview :src="scope.row.avatar" style="width: 45px; height: 45px" />
- </template>
- </el-table-column>
- <el-table-column
- label="系统账号"
- width="180"
- align="center"
- prop="userName"
- :show-overflow-tooltip="true"
- />
- <el-table-column
- label="绑定时间"
- width="180"
- align="center"
- prop="createTime"
- />
- <el-table-column
- label="操作"
- width="80"
- align="center"
- class-name="small-padding fixed-width"
- >
- <template slot-scope="scope">
- <el-button
- size="mini"
- type="text"
- icon="el-icon-delete"
- @click="unlockAuth(scope.$index, scope.row)"
- >解绑</el-button>
- </template>
- </el-table-column>
- </el-table>
- <div id="git-user-binding">
- <h4 class="provider-desc">你可以绑定以下第三方帐号用于CyberSpace系统</h4>
- <div id="authlist" class="user-bind">
- <a
- class="third-app"
- href="#"
- @click="authUrl('gitee');"
- title="使用 Gitee 账号授权登录"
- >
- <div class="git-other-login-icon">
- <svg-icon icon-class="gitee" />
- </div>
- <span class="app-name">Gitee</span></a
- >
- <a
- class="third-app"
- href="#"
- @click="authUrl('github');"
- title="使用 GitHub 账号授权登录"
- >
- <div class="git-other-login-icon">
- <svg-icon icon-class="github" />
- </div>
- <span class="app-name">Github</span></a
- >
- <a class="third-app" href="#" title="功能开发中...">
- <div class="git-other-login-icon">
- <svg-icon icon-class="weixin" />
- </div>
- <span class="app-name">WeiXin</span></a
- >
- <a class="third-app" href="#" title="功能开发中...">
- <div class="git-other-login-icon">
- <svg-icon icon-class="qq" />
- </div>
- <span class="app-name">QQ</span></a
- >
- </div>
- </div>
- </div>
- </template>
- <script>
- import { authUnlock, authBinding } from "@/api/system/auth";
- export default {
- props: {
- auths: {
- type: Array,
- },
- },
- data() {
- return {};
- },
- methods: {
- unlockAuth(index, row) {
- var _this = this;
- this.$modal
- .confirm('您确定要解除"' + row.source + '"的账号绑定吗?')
- .then(function () {
- return authUnlock(row.authId);
- })
- .then(() => {
- _this.auths.splice(index, 1);
- this.$modal.msgSuccess("解绑成功");
- })
- .catch(() => {});
- },
- authUrl(source) {
- authBinding(source).then(res => {
- top.location.href = res.msg;
- });
- }
- },
- };
- </script>
- <style type="text/css">
- .user-bind .third-app {
- display: -webkit-box;
- display: -ms-flexbox;
- display: flex;
- -webkit-box-orient: vertical;
- -webkit-box-direction: normal;
- -ms-flex-direction: column;
- flex-direction: column;
- -webkit-box-align: center;
- -ms-flex-align: center;
- align-items: center;
- min-width: 80px;
- float: left;
- }
- .user-bind {
- font-size: 1rem;
- text-align: start;
- height: 50px;
- margin-top: 10px;
- }
- .git-other-login-icon > img {
- height: 32px;
- }
- a {
- text-decoration: none;
- cursor: pointer;
- color: #005980;
- }
- .provider-desc {
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial,
- "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Liberation Sans",
- "PingFang SC", "Microsoft YaHei", "Hiragino Sans GB", "Wenquanyi Micro Hei",
- "WenQuanYi Zen Hei", "ST Heiti", SimHei, SimSun, "WenQuanYi Zen Hei Sharp",
- sans-serif;
- font-size: 1.071rem;
- }
- td > img {
- height: 20px;
- width: 20px;
- display: inline-block;
- border-radius: 50%;
- margin-right: 5px;
- }
- </style>
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |