国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

手摸手接入Github實(shí)現(xiàn)Oauth2第三方登錄

這篇具有很好參考價(jià)值的文章主要介紹了手摸手接入Github實(shí)現(xiàn)Oauth2第三方登錄。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

前言

最近在學(xué)習(xí)oauth2授權(quán)登錄流程,oauth2簡單來說就是接入第三方應(yīng)用(qq、微信、github、gitee等),不用在本站登錄,而是去請(qǐng)求第三方應(yīng)用的用戶信息完成登錄。

下面就一起來看一下如何接入github實(shí)現(xiàn)第三方登錄

前置操作

首先,我們需要在github中添加OAuth App,登錄你的github(如果還有無法登錄github的,請(qǐng)?jiān)谠u(píng)論區(qū)留言或私信我)

手摸手接入Github實(shí)現(xiàn)Oauth2第三方登錄,Demo,github,java,vue.js

手摸手接入Github實(shí)現(xiàn)Oauth2第三方登錄,Demo,github,java,vue.js

手摸手接入Github實(shí)現(xiàn)Oauth2第三方登錄,Demo,github,java,vue.js

手摸手接入Github實(shí)現(xiàn)Oauth2第三方登錄,Demo,github,java,vue.js

手摸手接入Github實(shí)現(xiàn)Oauth2第三方登錄,Demo,github,java,vue.js

手摸手接入Github實(shí)現(xiàn)Oauth2第三方登錄,Demo,github,java,vue.js

點(diǎn)擊注冊

手摸手接入Github實(shí)現(xiàn)Oauth2第三方登錄,Demo,github,java,vue.js

如果你成功執(zhí)行到這里,那么就恭喜你已經(jīng)把前置工作完成了

實(shí)戰(zhàn)演練

下面就以我個(gè)人的博客代碼為例,和大家一起實(shí)現(xiàn)github第三方登錄

博客地址:www.yuuu.online,

項(xiàng)目地址:蔚澤華 (yuuu-zehua) - Gitee.com

業(yè)務(wù)流程

我這里先說一下我項(xiàng)目的業(yè)務(wù)流程:用戶第一次使用github登錄,那么我會(huì)讓其與我的網(wǎng)站進(jìn)行綁定(郵箱);如果是非第一次使用,那么就直接登錄

話不多說,直接進(jìn)入!

業(yè)務(wù)代碼

因?yàn)槲业捻?xiàng)目是前后端分離的,所以一切請(qǐng)求都要過一遍前端代理,因此我寫了一個(gè)Loading頁,這也是我添加的github回調(diào)地址。

// Loading頁的執(zhí)行方法
oauth() {
            const urlParams = new URLSearchParams(window.location.search);
            const code = urlParams.get('code');
            const state = urlParams.get('state');
            if (code && code != '') {
                request.post('user/oauth?code=' + code + '&state=' + state).then(response => {
                    console.log(response);
                    if(response === undefined){
                        this.$router.push({ path: '/Login?login=9' });
                    }else{
                        setToken(response.token)
                        localStorage.setItem("userInfo", JSON.stringify(response.userInfo))
                        this.$router.push({ path: '/' });
                    }
                })
            }
        },

在這里會(huì)根據(jù)后端的返回去判斷是第一次登錄還是非第一次登錄,下面是后端接口實(shí)現(xiàn)

public ResponseResult oauth(String code) {

        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        BlogUserLoginVo blogUserLoginVo;
        try {
            String oauthToken = getOauthToken(code);
            GithubUser githubUser = getUserInfoWithGithub(oauthToken);

            queryWrapper.eq(User::getGithubId, githubUser.getId());
            User one = getOne(queryWrapper);
            if (one != null) {
                // 已經(jīng)綁定過用戶信息,直接登錄
                blogUserLoginVo = getBlogUserLoginVo(one);
                return ResponseResult.okResult(blogUserLoginVo);
            } else {
                redisCache.setCacheObject(code,githubUser);//注意這里
                Map<Integer,String> map = new HashMap<>();
                map.put(999, "未綁定");
                return ResponseResult.okResult(map);
            }
        } catch (IOException e) {
            throw new SystemException(AppHttpCodeEnum.SYSTEM_ERROR);
        }
    }

private BlogUserLoginVo getBlogUserLoginVo(User user) {
        // 獲取userId,生成token
        String jwt = JwtUtil.createJWT(user.getId().toString());
        // 把用戶信息存入redis
        LoginUser loginUser = new LoginUser();
        loginUser.setUser(user);
        loginUser.setPermissions(null);
        redisCache.setCacheObject(SystemConstants.BLOG_LOGIN_KEY + user.getId(), loginUser, 1800, TimeUnit.SECONDS);
        // 把token和userInfo封裝返回
        // 把user轉(zhuǎn)換為userInfo
        UserInfoVo userInfoVo = BeanCopyUtils.copyBean(user, UserInfoVo.class);
        BlogUserLoginVo blogUserLoginVo = new BlogUserLoginVo(jwt, userInfoVo);
        return blogUserLoginVo;
    }

private String getOauthToken(String code) throws IOException {
        String url = "https://github.com/login/oauth/access_token";

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));

        String requestBody = String.format("{\"client_id\":\"%s\",\"client_secret\":\"%s\",\"code\":\"%s\"}",
                clientId, clientSecret, code);

        HttpEntity<String> request = new HttpEntity<>(requestBody, headers);

        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, request, String.class);

        if (response.getStatusCode().is2xxSuccessful()) {
            // 解析JSON響應(yīng),獲取access_token字段
            String jsonString = JSON.toJSONString(response);
            JSONObject jsonObject = JSON.parseObject(jsonString);
            JSONObject body = jsonObject.getJSONObject("body");
            Object token = body.get("access_token");
            return token.toString();
        } else {
            throw new SystemException(AppHttpCodeEnum.SYSTEM_ERROR);
        }
    }

private GithubUser getUserInfoWithGithub(String oauthToken) throws IOException {
        String url = "https://api.github.com/user";
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "Bearer " + oauthToken);
        headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
        HttpEntity<Void> requestEntity = new HttpEntity<>(headers);
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, String.class);
        if (responseEntity.getStatusCode().is2xxSuccessful()) {
            String body = responseEntity.getBody();
            cn.hutool.json.JSONObject jsonObject = JSONUtil.parseObj(body);
            GithubUser githubUser = jsonObject.toBean(GithubUser.class);
            return githubUser;
        } else {
            throw new SystemException(AppHttpCodeEnum.SYSTEM_ERROR);
        }
    }

相關(guān)實(shí)體類,其實(shí)內(nèi)容有很多,但是在我項(xiàng)目里我只抽出了其中返回的幾個(gè)字段

public class GithubUser {
    private String login;
    private Integer id;
    private String nodeId;
    private String avatarUrl;
}

到這里,如果用戶已經(jīng)綁定過郵箱信息,那么就可以直接登錄主頁。如果用戶沒有綁定,就會(huì)跳轉(zhuǎn)到綁定頁。

這是我的綁定頁

手摸手接入Github實(shí)現(xiàn)Oauth2第三方登錄,Demo,github,java,vue.js

綁定的代碼也和前面的差不多

前端代碼

oauthWithGithub() {
            const urlParams = new URLSearchParams(window.location.search);
            const code = urlParams.get('code');
            const state = urlParams.get('state');
            if (!this.emailCaptchaUpdate) {
                this.$message.error('驗(yàn)證碼不能為空');
            } else {
                request.post('/user/oauth/github?code='+code, {
                    emailPassword: this.emailPassword,
                    confirmNewPassword: this.confirmNewPassword,
                    emailCaptchaUpdate: this.emailCaptchaUpdate,
                })
                    .then((response) => {
                        console.log(response)
                        this.$alert('綁定成功', '', {
                            confirmButtonText: '確定'
                        })
                        this.isButtonDisabled2 = false;
                        this.emailPassword = '';
                        this.emailCaptchaUpdate = '';
                        setToken(response.token)
                        localStorage.setItem("userInfo", JSON.stringify(response.userInfo))
                        this.$router.push({ path: '/' });
                    })
                    .catch((error) => {
                        console.log(error);
                    });
            }
        },

后端接口

public ResponseResult oauthGithub(ChangePassword user,String code) {
        String email = user.getEmailPassword();
        String captcha = user.getEmailCaptchaUpdate();
        if (StrUtil.isBlank(email)) {
            throw new SystemException(AppHttpCodeEnum.EMAIL_ISNULL);
        }
        if (StrUtil.isBlank(captcha)) {
            throw new SystemException(AppHttpCodeEnum.CAPTCHA_ISNULL);
        }
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getEmail, email);
        String cacheCaptcha = redisCache.getCacheObject(SystemConstants.MAIL_KEY + captcha);
        if (!captcha.equals(cacheCaptcha)) {
            return ResponseResult.errorResult(601, "請(qǐng)?jiān)贆z查一下驗(yàn)證碼~");
        } else {
            redisCache.deleteObject(SystemConstants.MAIL_KEY + captcha);
        }
        User existingUser = getOne(queryWrapper);
        BlogUserLoginVo blogUserLoginVo;
        // 還記得上面讓大家注意的地方嗎?如果忘記了速速回滾查看!
        // 因?yàn)間ithub的code只能用一次,本來想使用ThreadLocal,但是實(shí)現(xiàn)起來總報(bào)錯(cuò),就直接用            
        // redis存儲(chǔ)
        GithubUser githubUser = redisCache.getCacheObject(code);
        if (existingUser == null) {
            // 新增
            User userByGithub = new User();
            userByGithub.setGithubId(githubUser.getId());
            userByGithub.setAvatar(githubUser.getAvatarUrl());
            userByGithub.setEmail(user.getEmailPassword());
            userByGithub.setPassword(passwordEncoder.encode(SystemConstants.DEFAULT_PASSWORD));
            userByGithub.setNickName(githubUser.getNodeId());
            userByGithub.setUserName(githubUser.getLogin());
            save(userByGithub);
            // 用戶登錄
            blogUserLoginVo = getBlogUserLoginVo(userByGithub);
        } else {
            // 修改
            existingUser.setGithubId(githubUser.getId());
            updateById(existingUser);
            // 用戶登錄
            blogUserLoginVo = getBlogUserLoginVo(existingUser);
        }
        // 用完就及時(shí)刪除,避免資源浪費(fèi)
        redisCache.deleteObject(code);
        return ResponseResult.okResult(blogUserLoginVo);
    }

到這里,就實(shí)現(xiàn)了全部的功能,大家可以去盡情的嘗試了!

總結(jié)

Oauth2實(shí)現(xiàn)的原理就是拿code去換第三方的token,然后再用token去獲取用戶信息,看起來很容易,但是實(shí)現(xiàn)起來有點(diǎn)麻煩,其實(shí)也不是難,就是麻煩,你需要去看每個(gè)廠商的api文檔,每一個(gè)還都不一樣,就比如github和gitee。

我想大家在實(shí)現(xiàn)時(shí)也會(huì)常常出現(xiàn)接口超時(shí),沒有辦法,我的代碼在本地不會(huì)超時(shí),但是部署在華為云服務(wù)器上就反復(fù)報(bào)接口超時(shí),后面我也會(huì)進(jìn)行優(yōu)化。謝謝大家觀看。

后續(xù)

后面也是成功解決了github超時(shí)的問題,給大家說一下方法。

我是自己在Cloudflare開了一個(gè)代理,把自己的域名代理到了github
如果有需要我的代理域名的小伙伴可以私信我。如果有需要出教程的也可以在評(píng)論區(qū)留言,需要的人多了就繼續(xù)手摸手實(shí)現(xiàn)github代理。文章來源地址http://www.zghlxwxcb.cn/news/detail-764279.html

到了這里,關(guān)于手摸手接入Github實(shí)現(xiàn)Oauth2第三方登錄的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【Oauth2.0 單點(diǎn)登錄 + 第三方授權(quán)認(rèn)證】用戶認(rèn)證、授權(quán)模式

    【Oauth2.0 單點(diǎn)登錄 + 第三方授權(quán)認(rèn)證】用戶認(rèn)證、授權(quán)模式

    本文主要對(duì) SpringSecurity Oauth 2.0 用戶認(rèn)證,授權(quán)碼授權(quán)模式、密碼授權(quán)模式,以及授權(quán)流程進(jìn)行講解 開發(fā)中,有些功能只有管理員才有,普通用戶是沒有的。即需要對(duì)用戶的身份進(jìn)行認(rèn)證,是管理員還是普通用戶。認(rèn)證方式有兩種: 身份認(rèn)證: 用戶在訪問相應(yīng)資源時(shí)對(duì)用戶

    2023年04月08日
    瀏覽(25)
  • Spring Boot 最新版3.x 集成 OAuth 2.0實(shí)現(xiàn)認(rèn)證授權(quán)服務(wù)、第三方應(yīng)用客戶端以及資源服務(wù)

    Spring Boot 最新版3.x 集成 OAuth 2.0實(shí)現(xiàn)認(rèn)證授權(quán)服務(wù)、第三方應(yīng)用客戶端以及資源服務(wù)

    Spring Boot 3 已經(jīng)發(fā)布一段時(shí)間,網(wǎng)上關(guān)于 Spring Boot 3 的資料不是很多,本著對(duì)新技術(shù)的熱情,學(xué)習(xí)和研究了大量 Spring Boot 3 新功能和新特性,感興趣的同學(xué)可以參考 Spring 官方資料全面詳細(xì)的新功能/新改進(jìn)介紹 Spring 版本升級(jí)到6.x JDK版本至少17+ … 新特性有很多,本文主要針對(duì)

    2024年02月02日
    瀏覽(97)
  • 到底要不要,手摸手指導(dǎo)下屬?

    leader的 核心職責(zé) 是: (1)對(duì)上 ,完成老板交予的任務(wù); (2)對(duì)同事 ,為隊(duì)友賦能; (3)對(duì)下 ,為下屬搭舞臺(tái)唱戲,幫助下屬解決問題,幫助下屬成長和提升; 其中,幫助下屬成長和提升,指導(dǎo)與培養(yǎng)員工,是非常重要的一塊,新晉管理者心中可能會(huì)有這樣 一些疑問

    2024年02月05日
    瀏覽(21)
  • OAuth2.0從入門到實(shí)戰(zhàn)(附github地址)

    OAuth2.0從入門到實(shí)戰(zhàn)(附github地址)

    OAuth 是一個(gè)開放標(biāo)準(zhǔn) ,該標(biāo)準(zhǔn)允許用戶讓第三方應(yīng)用訪問該用戶在某一網(wǎng)站上存儲(chǔ)的私密資源(如頭像、照片、視頻等),而在這個(gè)過程中無需將用戶名和密碼提供給第三方應(yīng)用。實(shí)現(xiàn)這一功能是通過提供一個(gè)令牌(token),而不是用戶名和密碼來訪問他們存放在特定服務(wù)提

    2023年04月08日
    瀏覽(19)
  • 手摸手帶你初探Vue 3.0

    距離Vue 3.0正式發(fā)布已經(jīng)過去一段時(shí)間了,2月7日Vue團(tuán)隊(duì)正式宣布Vue 3正式成為新的默認(rèn)版本。最近接觸的新項(xiàng)目也使用Vue 3.0來開發(fā),因此有必要對(duì)它進(jìn)行一波總結(jié)和學(xué)習(xí)。 在最開始的時(shí)候,Vue僅僅是一個(gè)運(yùn)行時(shí)庫。但經(jīng)過多年的發(fā)展,它已經(jīng)逐漸變成了一臺(tái)包含許多子項(xiàng)目的

    2024年02月16日
    瀏覽(24)
  • SpringSecurity:OAuth2 Client 結(jié)合GitHub授權(quán)案例(特簡單版)

    SpringSecurity:OAuth2 Client 結(jié)合GitHub授權(quán)案例(特簡單版)

    本隨筆說明:這僅作為OAuth2 Client初次使用的案例,所以寫得很簡單,有許多的不足之處。 OAuth2 Client(OAuth2客戶端)是指使用OAuth2協(xié)議與授權(quán)服務(wù)器進(jìn)行通信并獲取訪問令牌的應(yīng)用程序或服務(wù)。OAuth2客戶端代表最終用戶(資源擁有者)向授權(quán)服務(wù)器請(qǐng)求授權(quán),并使用授權(quán)后的

    2024年02月03日
    瀏覽(22)
  • 手摸手教你寫任務(wù)中心-積分領(lǐng)取&消耗&回收

    手摸手教你寫任務(wù)中心-積分領(lǐng)取&消耗&回收

    繼上一篇簽到任務(wù)之后呢, 就有朋友讓我寫一下任務(wù)積分的領(lǐng)取和使用, 以及回收; 其實(shí)前面兩種都不難, 就只是積分的加減而已, 真正麻煩的是回收, 有回收的話你就需要考慮到每筆積分存在多種狀態(tài)的可能了; 明細(xì)表(mysql) 記錄積分的每一筆獲取, 消耗的回收的記錄, 并且回收

    2024年02月08日
    瀏覽(22)
  • 手摸手帶你 在Windows系統(tǒng)中安裝Istio

    手摸手帶你 在Windows系統(tǒng)中安裝Istio

    通過負(fù)載均衡、服務(wù)間的身份驗(yàn)證、監(jiān)控等方法,Istio 可以輕松地創(chuàng)建一個(gè)已經(jīng)部署了服務(wù)的網(wǎng)絡(luò),而服務(wù)的代碼只需很少更改甚至無需更改。 通過在整個(gè)環(huán)境中部署一個(gè)特殊的 sidecar 代理為服務(wù)添加 Istio 的支持,而代理會(huì)攔截微服務(wù)之間的所有網(wǎng)絡(luò)通信,然后使用其控制

    2024年02月06日
    瀏覽(22)
  • 不用魔法,快速、手摸手上線Midjourney!【附源碼】【示例】

    不用魔法,快速、手摸手上線Midjourney!【附源碼】【示例】

    首先來一波感謝: 感謝laf提供贊助,目前可以免費(fèi)使用Midjourney進(jìn)行開發(fā)和測試。 感謝白夜、米開朗基楊@sealos.io的耐心解答,讓我對(duì)laf有了更多的使用與了解。 什么是laf?來了解下。 文末有【示例】 廢話不多說,進(jìn)入正題。 laf在做一個(gè)活動(dòng),可以使用快速上手Midjourney《人

    2024年02月05日
    瀏覽(19)
  • 手摸手2-springboot編寫基礎(chǔ)的增刪改查

    手摸手2-springboot編寫基礎(chǔ)的增刪改查

    創(chuàng)建controller層 實(shí)現(xiàn) test 表中的添加、修改、刪除及列表查詢接口(未分頁) 添加service層接口 service層實(shí)現(xiàn) 添加mapper層 mapper層對(duì)應(yīng)的sql 添加掃描注解,對(duì)應(yīng)sql文件的目錄

    2024年02月10日
    瀏覽(14)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包