AppId、AppSecret
创建扫码登陆应用授权,获得appid和appsecret
前端
推荐将登录二维码内嵌到自己的页面中,我在开发时将二维码放在一个隐藏的界面中点击扫码登录按钮会显现。但是因为我对html中id的优先级不清楚二维码总是不出来,但放在主页面是正常出现的,我就没有选择内嵌。
跳转钉钉扫码登录页面
// 钉钉扫码代码
let appid = "dingoatx********wjkaq8n";
let appSecret =
"yqfqoN9mbt4ndpIQ6M**********_*********mpEts5LzP9zIct70Qn";
let url = "http://localhost:8080/login";
let state = new Date();
window.location.href =
"https://oapi.dingtalk.com/connect/qrconnect?appid=" +
appid +
"&response_type=code&scope=snsapi_login&state=" +
state +
"&redirect_uri=" +
url;
在填写的回调页面中获得code和state
// 导入获取地址栏参数,代码在后面
import { getUrlKey } from "@/getUrlKey";
var port = require("../../../../apiconfig");
// 进入页面就执行
mounted() {
// ......
this.getCode();
},
methods: {
// ......
getCode() {
let code = getUrlKey("code");
let state = getUrlKey("state");
if (code != null) {
// 设置cookie
cookie.set("STATE", state);
// 后端API接收code接口
var api = port.dtoauth;
Axios.post(
api,
JSON.stringify({
js_code: code
}),
{
headers: {
"Content-Type": "application/x-www-form-urlencoded",
Accept: "application/json"
}
}
)
.then(res => {
// ......
})
.catch(err => {
// ......
})
}
}
GetUrlKey.js
export function getUrlKey(name) {
return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.href) || [, ""])[1].replace(/\+/g, '%20')) || null
}
后端
// 根据timestamp, appSecret计算签名值
func GetSignature(timestamp string) string {
h := hmac.New(sha256.New, []byte(dtconf.AppSecret))
h.Write([]byte(timestamp))
// base64编码转换为字符串
sha := base64.StdEncoding.EncodeToString(h.Sum(nil))
// 因为签名中可能包含特殊字符(+、=),需要对字符串进行url编码
return url.QueryEscape(sha)
}
// GerDTUserInfo 获得钉钉用户的信息
func GerDTUserInfo(code string) (userinfo pb.RespInfoDTSmall, err error) {
// code是前端扫码之后重定向网址获得
// 当前时间戳,单位是毫秒
timestamp := strconv.FormatInt(time.Now().UnixNano()/1e6, 10)
// 获取签名值
signature := GetSignature(timestamp)
// 拼接url
requrl := dtconf.Url + "?signature=" + signature + "×tamp=" + timestamp + "&accessKey=" + dtconf.AppId
// 设置post参数
var temp Temp
temp.Tmp_auth_code = code
// 序列化JSON参数
bytesData, _ := json.Marshal(temp)
reader := bytes.NewReader(bytesData)
// 创建一个client
client := http.Client{}
request, err := http.NewRequest("POST", requrl, reader)
if err != nil {
fmt.Println(err)
}
// 设置json请求方式
request.Header.Set("Content-Type", "application/json; charset=utf-8")
// 进行请求
response, err := client.Do(request)
if err != nil {
fmt.Println(err)
}
// defer关闭流
defer response.Body.Close()
// 获得json数据
body, err := ioutil.ReadAll(response.Body)
// 反序列化json数据至uerinfo
err = json.Unmarshal(body, &userinfo)
if err != nil {
fmt.Println(err)
}
// 返回用户信息
return userinfo, nil
}
得到用户信息返回至前端。