spirngboot+vue 同时整合QQ和微信和gitee登录等第三方登录

概述

 本次整合的多个第三方登录平台都是基于oauth2.0协议的平台,使用的前提是有OAuth2.0协议有所了解,推荐阅读:阮一峰的OAuth 2.0 的一个简单解释。本次主要使用的开源组件是JustAuth

springboot后端

POM文件

        <dependency>
            <groupId>com.xkcoding.justauth</groupId>
            <artifactId>justauth-spring-boot-starter</artifactId>
            <version>${justauth-spring-boot-starter.version}</version>
        </dependency>
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.2.2</version>
            <scope>provided</scope>
        </dependency>

application 配置

justauth:
  type:
    QQ:
      client-id: 11111111111111111
      client-secret: 2a64d0f6011111111111111111
      redirect-uri: http://roroschach.club/oauth2/callback/qq
      ignoreCheckRedirectUri: true
    GITEE:
      client-id: 66ac9fd4ddafd0dbe8311111111111111111
      client-secret: 9ed19d2fc9a3c7611111111111111111
      redirect-uri: http://127.0.0.1:8888/oauth2/callback/gitee
    OSCHINA:
      client-id: NH11111111111111111
      client-secret: C8dtfJSyGys11111111111111111
      redirect-uri: http://127.0.0.1:8888/oauth2/callback/oschina

controller

@RequestMapping("oauth2")
@Api(tags = "oauth2", value = "Oauth2Controller")
@RestController
@Slf4j
public class Oauth2Controller {

    @Autowired
    AuthRequestFactory factory;
    /**
     * 获取第三方登录平台信息
     *
     * @param platform 第三方登录平台
     * @return cn.com.zsw.gblog.vo.R
     * @author shiwangzhou
     * @date 2021-06-09 16:52
     **/
    @GetMapping("{platform}/info")
    public R getLoginInfo(@PathVariable String platform) {
        AuthRequest authRequest = factory.get(platform);
        String authorize = authRequest.authorize(AuthStateUtils.createState());
        log.info(authorize);
        return R.SUCCESS.data(authorize);
    }

    @RequestMapping("/callback/{source}")
    @Transactional
    public R login(@PathVariable("source") String source, AuthCallback callback, HttpServletRequest request) throws Exception {
        log.info("进入callback:" + source + " callback params:" + JSONObject.toJSONString(callback));
        AuthRequest authRequest = factory.get(source);
        AuthResponse<AuthUser> response = authRequest.login(callback);
        log.info(JSONObject.toJSONString(response));
        if (response.ok()) {
            final UserInfoVO userInfoVO = oauthService.oauthCallback(response.getData());
            return R.SUCCESS.data(userInfoVO);
        }
        return R.status(500).msg("登录失败");

    }
}

 

前端

新建 oauthCallback.vue 

<template>

</template>
<script>
export default {
  name: "oauthCallback",
  data() {
    return {
      authCallback: {
        platform: "",
        code: "",
        state: "",
      },
    };
  },
  created() {
    this.authCallback.platform = this.$route.params.platform;
  },
  mounted() {
    var code = this.$utils.getUrlKey("code");
    var state = this.$utils.getUrlKey("state");
    this.authCallback.code = code;
    this.authCallback.state = state;
    //server-side模式
    if (code && typeof code != "undefined") {
      console.log("server-side模式:" + code);
      //获取到token就是已经登录了
      var token = this.$store.getters.token;
      if (token && typeof token != "undefined") {
        this.$router.push("/");
      }
      //未登录则执行登录
      else {
        this.$store
          .dispatch("user/authCodelogin", this.authCallback)
          .then(() => {
            location.reload();
          });
      }
    }
  },
};
</script>

<style>
</style>

添加路由

import Vue from 'vue'
import VueRouter from 'vue-router'
import store from '@/store'

Vue.use(VueRouter)

const routes = [
    {
        path: '/oauth2/callback/:platform',
        name: 'qqCallback',
        component: () => import('../views/oauth/oauthCallback.vue'),
        meta: { title: 'Gitee登录成功后回调'}
    }

]

const router = new VueRouter({
    // mode: 'hash',  //hash模式的工作原理是hashchange事件,可以在window监听hash的变化。
    mode: 'history', 
    base: process.env.BASE_URL,
    routes
})
router.beforeEach((to, from, next) => {
    let title = 'Gblog'
    if (to.meta.params){
        title = `${to.meta.title}:${to.params[to.meta.params] || ''} - ${title}`
    }else {
        title = `${to.meta.title} - ${title}`
    }
    document.title = title
    store.dispatch('app/setLoading', true);
    next();
})
router.afterEach((to, from) => {
    // 最多延迟 关闭 loading
    setTimeout(() => {
        store.dispatch('app/setLoading', false);
    }, 1500)
})
export default router

登录逻辑

import { login, logout, qqLogin, oauth2LoginCallback, getUserInfo } from '@/api/index'
import { getToken, setToken, removeToken, getAvatar, setAvatar, getName, setName, removeName, removeAvatar,getPermission,setPermission,removePermission } from '@/utils/auth'

const getDefaultState = () => {
  return {
    token: getToken(),
    name: getName(),
    avatar: getAvatar(),
    permission: getPermission()
  }
}

const state = getDefaultState()

const mutations = {
  RESET_STATE: (state) => {
    Object.assign(state, getDefaultState())
  },
  SET_TOKEN: (state, token) => {
    state.token = token
  },
  SET_NAME: (state, name) => {
    state.name = name
  },
  SET_AVATAR: (state, avatar) => {
    state.avatar = avatar
  },
  SET_PERMISSION: (state, permission) => {
    state.permission = permission
  }
}

const actions = {

  //QQ互联的server-side模式,
  authCodelogin({ commit }, authcallback) {
    console.log("qqCodelogin----code:" + authcallback.code);
    return new Promise((resolve, reject) => {
      oauth2LoginCallback(authcallback.platform,authcallback).then(res => {
        let data = res.data
        console.log("server-side模式,  data==" + JSON.stringify(data));
        console.log("server-side模式,  data==" + data.token);
        commit('SET_TOKEN', data.token)
        commit('SET_NAME', data.nickname)
        commit('SET_AVATAR', data.avatar)
        commit('SET_PERMISSION', data.permission)
        setPermission(data.permission)
        setToken(data.token)
        setAvatar(data.avatar)
        setName(data.nickname)
        resolve()
      }).catch(error => {
        reject(error)
      })
    })
  },


}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

对接后端接口

import request from '@/utils/request'

//获取Oauth登录接口信息
export function getOauthLoginInfo(platgorm) {
    return request({
        url: '/oauth2/'+platgorm+'/info',
        method: 'get'
    })
}
//获取Oauth登录接口信息
export function oauth2LoginCallback(platgorm,data) {
    return request({
        url: '/oauth2/callback/'+platgorm,
        method: 'post',
        params:data
    })
}

// 请求用户信息
export function getUserInfo() {
    return request({
        url: '/user/info',
        method: 'get'
    })
}

后记

全部代码在

https://gitee.com/gitee_zsw/Gblog

https://gitee.com/gitee_zsw/springboot-blog


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Rorschach01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值