龙海网站建设,wordpress可以自定义模型吗,深圳品牌网站制作多少钱,做网站语言知乎钉钉的的官方开发文档中只给出了java实现三方登录的#xff0c;我们准备用go语言来实现
实现网页方式登录应用#xff08;登录第三方网站#xff09; - 钉钉开放平台
首先就是按照文档进行操作#xff0c;备注好网站的信息
获得应用凭证#xff0c;我们后面会用到
之后…钉钉的的官方开发文档中只给出了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%sresponse_typecodescopesnsapi_loginstate%sredirect_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/userAccessTokenpayload : 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/mereq, _ : 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}))
}