go實現釘釘三方登錄

釘釘的的官方開發文檔中只給出了java實現三方登錄的,我們準備用go語言來實現

實現網頁方式登錄應用(登錄第三方網站) - 釘釘開放平臺

首先就是按照文檔進行操作,備注好網站的信息

獲得應用憑證,我們后面會用到

之后配置回調域名,用于后續前端頁面重定向使用

開通用戶的個人信息權限

代碼如下

控制層

// RedirectToDingTalkLogin
// @Description: 將用戶重定向到釘釘登錄授權頁
// @param        c *gin.Context
func RedirectToDingTalkLogin(c *gin.Context) {appId := "**這里寫你的Client ID**"redirectUri := url.QueryEscape("**這里寫你的回調地址**") // 釘釘回調地址state := "random-state"                                             //防止CSRF,可選url := fmt.Sprintf("https://oapi.dingtalk.com/connect/qrconnect?appid=%s&response_type=code&scope=snsapi_login&state=%s&redirect_uri=%s",appId, state, redirectUri)c.Redirect(http.StatusFound, url)
}// GetDingTalkToken
// @Description: 處理釘釘回調信息
// @param        c *gin.Context
func GetDingTalkToken(c *gin.Context) {authCode := c.DefaultQuery("authCode", "")if authCode == "" {response.Failed(c, http.StatusBadRequest, response.NewAppErr(globals.StatusBadRequest, nil, nil))return}accessToken, err := logics.GetAccessToken(authCode)if err != nil {response.Failed(c, http.StatusInternalServerError, response.NewAppErr(globals.StatusInternalServerError, err, nil))return}//獲取用戶信息userInfo, err := logics.GetDingTalkUserInfo(accessToken)if err != nil {response.Failed(c, http.StatusInternalServerError, response.NewAppErr(globals.StatusInternalServerError, err, nil))return}logics.ThirdPartLogin(c, userInfo, "dingTalk")
}

業務層代碼

var dingTalkConf = requests.Conf{ClientId:     "你的client ID",ClientSecret: "你的ClientSecret",RedirectUrl:  "你的回調地址",
}// GetAccessToken
// @Description: 獲取釘釘通行token
// @param        authCode string
// @return       string
// @return       error
func GetAccessToken(authCode string) (string, error) {api := "https://api.dingtalk.com/v1.0/oauth2/userAccessToken"payload := url.Values{}payload.Set("clientId", dingTalkConf.ClientId)payload.Set("clientSecret", dingTalkConf.ClientSecret)payload.Set("code", authCode)payload.Set("grantType", "authorization_code")resp, err := http.PostForm(api, payload)if err != nil {return "", fmt.Errorf("post token error: %v", err)}defer resp.Body.Close()body, _ := ioutil.ReadAll(resp.Body)if resp.StatusCode != http.StatusOK {return "", fmt.Errorf("failed to get token: %s", string(body))}var tokenResp requests.TokenResponseif err = json.Unmarshal(body, &tokenResp); err != nil {return "", fmt.Errorf("parse token json error: %v", err)}return tokenResp.AccessToken, nil
}// GetDingTalkUserInfo
// @Description: 通過token獲取用戶信息
// @param        accessToken string
// @return       *models.User
// @return       error
func GetDingTalkUserInfo(accessToken string) (map[string]interface{}, error) {api := "https://api.dingtalk.com/v1.0/contact/users/me"req, _ := http.NewRequest("GET", api, nil)req.Header.Set("x-acs-dingtalk-access-token", accessToken)client := &http.Client{}resp, err := client.Do(req)if err != nil {return nil, fmt.Errorf("get user info error: %v", err)}defer resp.Body.Close()body, _ := ioutil.ReadAll(resp.Body)if resp.StatusCode != http.StatusOK {return nil, fmt.Errorf("failed to get user info: %s", string(body))}var userInfo map[string]interface{}if err = json.Unmarshal(body, &userInfo); err != nil {return nil, fmt.Errorf("parse user json error: %v", err)}return userInfo, nil
}// ThirdPartLogin
// @Description: 根據第三方信息登錄并生成token
// @param        c *gin.Context
// @param        userInfo map[string]interface{}
// @param        provider string
func ThirdPartLogin(c *gin.Context, userInfo map[string]interface{}, provider string) {db := globals.DB//判斷用戶是否掃碼登錄過userId, err := repositories.CheckHistoryLogin(db, userInfo["id"].(string), provider)if err != nil {response.Failed(c, http.StatusInternalServerError, response.NewAppErr(globals.StatusInternalServerError, err, nil))}if userId == 0 {//判斷用戶是否注冊過user := repositories.QueryUserByEmail(db, userInfo["email"].(string))if user == nil {//沒注冊過直接跳轉至注冊return}//將三方登錄記錄插入記錄表err = repositories.InsertOtherLogin(db, userInfo["id"].(string), provider, user.ID)if err != nil {response.Failed(c, http.StatusInternalServerError, response.NewAppErr(globals.StatusInternalServerError, err, nil))return}}// 生成tokenid := userIdtok, err := token.GenerateToken(id, userInfo["email"].(string))if err != nil {globals.Log.Errorf(err.Error())response.Failed(c, http.StatusInternalServerError, response.NewAppErr(globals.StatusInternalServerError, err, nil))return}response.Success(c, http.StatusOK, response.NewAppData(globals.StatusOK, response.DataSuccess, gin.H{"Token": tok, "userinfo": userInfo}))
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/907095.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/907095.shtml
英文地址,請注明出處:http://en.pswp.cn/news/907095.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

一、OpenCV的基本操作

目錄 1、OpenCV的模塊 2、OpenCV的基礎操作 2.1圖像的IO操作 2.2繪制幾何圖形 2.3獲取并修改圖像中的像素點 2.4 獲取圖像的屬性 2.5圖像通道的拆分與合并 2.6色彩空間的改變 3、OpenCV的算數操作 3.1圖像的加法 3.2圖像的混合 3.3總結 1、OpenCV的模塊 2、OpenCV的基…

虛擬機配置橋接,遠程工具直接訪問

虛擬機網絡配置 前言windows下安裝linux虛擬機配置網絡1、設置虛擬機網絡模式:橋接模式2、配置網絡參數1、查看本機電腦連接的網絡情況2、打開虛擬機,編輯配置文件3、編輯虛擬網絡 3、測試連通性 前言 好不容易裝上了虛擬機,輸入命令時又發現…

RabbitMQ 概述與安裝

MQ 作用與介紹 MQ 是什么 MQ (message queue),從字面意思看是一個隊列, FIFO 先進先出,只不過里面存放的內容是 消息 消息 可以比較簡單,比如只包含 文本字符串,JSON 等;也可以很復雜,比如 內嵌對象 等 MQ 多用于分布式系統之間進行通信 系統之間的調用通常有兩種方式: 1…

如何在Vue中實現延遲刷新列表:以Element UI的el-switch為例

如何在Vue中實現延遲刷新列表:以Element UI的el-switch為例 在開發過程中,我們經常需要根據用戶操作或接口響應結果來更新頁面數據。本文將以Element UI中的el-switch組件為例,介紹如何在狀態切換后延遲1秒鐘再調用刷新列表的方法&#xff0…

CSS2相關知識點

CSS2相關知識點 CSS的編寫位置樣式種類樣式表的優先級 CSS選擇器CSS基本選擇器通配選擇器元素選擇器類選擇器ID選擇器 復合選擇器HTML元素間的關系交集選擇器并集選擇器后代選擇器子代選擇器兄弟選擇器屬性選擇器偽類選擇器偽元素選擇器 顏色的表示表示方式一:顏色名…

centos yum源,docker源

yum源repo文件: wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repodocker源repo文件: yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo安裝docker和docker c…

深入探索AI模型工程:算法三大門派與監督學習的魅力

在當今人工智能蓬勃發展的時代,AI系統正逐漸滲透到我們生活的方方面面。從智能語音助手到自動駕駛汽車,從醫療影像診斷到金融風險預測,AI的應用場景無處不在。然而,構建一個高效、可靠的AI系統并非易事,它需要我們從宏…

[De1CTF 2019]SSRF Me

算是我第一次正兒八經的分析python代碼了 from flask import Flask, request import socket import hashlib import urllib import sys import os import jsonreload(sys) sys.setdefaultencoding(latin1)app Flask(__name__) # 創建一個Flask應用實例 secret_key os.ura…

Halcon 圖像預處理②

非線性圖像分段變化: 先窗體打開圖片 對數非線性變化: 結果圖像的亮度/對比度顯著增加 log_image(Image,LogImag1,e) 參數1:輸入圖像 參數2: 輸出圖像 參數3:底數 log_image(Image,LogImage2,0.1) 圖像結果亮度和…

云原生安全之網絡IP協議:從基礎到實踐指南

🔥「炎碼工坊」技術彈藥已裝填! 點擊關注 → 解鎖工業級干貨【工具實測|項目避坑|源碼燃燒指南】 一、基礎概念 IP協議(Internet Protocol)是互聯網通信的核心協議族之一,負責在設備間傳遞數據包。其核心特性包括&…

QML學習08Text

Text 1、顏色(color)2、獲取寬度和高度(contentWidth、contentHeight)3、字體格式(font)4、文本樣式(textFormat)5、超鏈接 1、顏色(color) //顏色Text {colo…

Python網絡編程深度解析

目錄 一、網絡編程概述 二、TCP與UDP協議詳解 1.TCP協議:可靠傳輸的基石 2.UDP協議:高效但不可靠的傳輸 3. TCP與UDP對比 三、Socket編程模型 1. Socket基礎 2.TCP服務器實現詳解 3. UDP服務器實現詳解 四、進階應用:簡易聊天程序 …

ElasticSearch導讀

ElasticSearch 簡介:ElasticSearch簡稱ES是一個開源的分布式搜素和數據分析引擎。是使用Java開發并且是當前最流行的開源的企業級搜索引擎,能夠達到近實時搜索,它專門設計用于處理大規模的文本數據和實現高性能的全文搜索。它基于 Apache Luc…

【后端高階面經:數據庫篇】18、分布式事務:如何在分庫分表中實現高性能與一致性?

一、分布式事務核心挑戰:分庫分表下的一致性困境 在分布式系統架構中,分庫分表通過將數據分散存儲提升了擴展性和性能,但卻打破了傳統單庫事務的邊界,使得分布式事務成為保障數據一致性的核心難題。其挑戰主要體現在以下三方面: 1.1 ACID特性的分布式撕裂 原子性(Atomi…

Tailwind css實戰,基于Kooboo構建AI對話框頁面(一)

在當今數字化時代,AI 助手已成為網站和應用不可或缺的一部分。本文將帶你一步步使用 Tailwind CSS 和 Kooboo 構建一個現代化的 AI 對話界面框。 一、選擇 Kooboo平臺 的核心優勢 智能提示:在輸入 class 屬性時,會自動觸發 Tailwind CSS 規則…

python學習day2:進制+碼制+邏輯運算符

進制 Python 中的進制表示與轉換 進制的基本概念 二進制、八進制、十進制、十六進制的定義與特點不同進制在計算機科學中的應用場景 Python 中的進制表示 二進制表示:使用 0b 前綴八進制表示:使用 0o 前綴十六進制表示:使用 0x 前綴示例…

ROS2學習(11)------ROS2通信接口

操作系統:ubuntu22.04 IDE:Visual Studio Code 編程語言:C11 ROS版本:2 ROS 2 提供了多種通信接口,用于節點之間的數據交換。這些接口主要包括話題(Topics)、服務(Services)、動作&…

STM32G0xx基于串口(UART)Ymodem協議實現OTA升級包括Bootloader、上位機、應用程序

STM32G0xx基于串口Ymodem協議實現OTA升級包括Bootloader、上位機、應用程序 例程說明一、串口相關的底層配置二、OTA相關的應用層三、Flash相關的操作四、Flash存儲參數相關五、核心部分Ymodem相關六、其他宏配置七、主函數八、使用Python合并文件九、測試結果有疑問歡迎加交流…

Jenkins實踐(6):配置“構建歷史的顯示名稱,加上包名等信息“

Jenkins實踐(6):配置“構建歷史的顯示名稱,加上包名等信息“ 版本:Jenkins 4.262.2 需求:想要在構建歷史中展示,本次運行的是哪個版本或哪個包 操作步驟: 1、先安裝插件Build Name and Description Setter 2、Set Build Name 3、構建歷史處查看展示 插件特性說明 安裝依賴…

快速解決azure aks aad身份和權限問題

現狀分析 AKS cluster 1.31.8啟用aad 身份驗證和kubernetes RBAC 當嘗試執行kubectl get node命令時,系統返回以下錯誤信息: Error from server (Forbidden): nodes is forbidden: User "357517e8-4df5-4daa-88b4-94a84d763ec5" cannot list…