Third party authorization login of OAUTH
hello, I'm Nezha, the Little Devil boy. Welcome to click and pay attention. There are updates, which will be presented to you for the first time
Fat sir: Little Devil boy, I received a request today. I expect us to make a third-party login function. Users can log in to our web through third-party authorization
Little Devil boy: aha? Do you have eyebrows
Fat sir: of course, I know you can log in through wechat, nailing, github and so on
Little Devil boy: do you know how to achieve it? Tell me and let me learn
Fat sir: will you take me to a fast car?
Little Devil boy: This.. You.. I'll teach you how to ride like a horse, only if you tell me how to do it
Fat sir: steady, deal.
In fact, the principle of third-party login belongs to OAuth mechanism, which is mainly used to issue token s. Now OAuth has reached oauth2 0
In Baidu Encyclopedia's words:
OAuth2.0 is a continuation of OAuth protocol, but it is not forward compatible with OAuth 1.0 (that is, OAuth 1.0 is completely abolished). OAuth 2.0 focuses on the simplicity of client developers. Either represent the user through the approved interaction between the resource owner and the HTTP service provider, or allow the third-party application to obtain access rights on behalf of the user. At the same time, it provides a special certification process for Web applications, desktop applications and mobile phones, and living room equipment. In October 2012, OAuth 2.0 protocol was officially released as RFC 6749 [1].
There are four main ways. I'll give you a brief list:
- Authorization code
- Hidden
- Cipher type
- Client credentials
Draw a diagram for you to feel
Of course, I'm not telling you about OAuth's own principles and technologies. I'm going to tell you directly how to implement the interface of docking nails I just mentioned, because the development documents of nails have been modified several times,
In addition, the expression in the document is also difficult to understand. In view of the fact that you took me on a flying ride, I'll tell you how to obtain the authorization of nails and the organizational structure of the company corresponding to the use of nails (which must have the permission of the company administrator)
Nailing development documents do not have the SDK and source code of golang version, so we will implement it ourselves
Tools used in the early stage
- Interface debugging with postman
- golang language through Golan compiler access_token and temporary code to obtain unionid
Get access_token
Request address
https://oapi.dingtalk.com/gettoken?appkey=xxx&appsecret=xxx
Request method
- GET
- query
- appkey
- appsecret
appkey and appsecret here are the application data in H5 micro application
response
{ "errcode": 0, "access_token": "4dbda4ddb82dxxxxxx138afab15655", "errmsg": "ok", "expires_in": 7200 }
Scan code / use account password – obtain temporary code
Important description of parameters
-
appId
appId of login app
-
redirect_uri - callback domain name
Redirect url address. After successful login, the web page will be redirected to redirect_uri
redirect_ The URI must be configured on the nailing open platform, or you will not have access to the following address. For example, fill in Baidu's address for this parameter
-
LOGO address
The address of an accessible picture on the network is as follows:
Direct access code scanning login
https://oapi.dingtalk.com/connect/qrconnect?appid=xxxx&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=https://www.baidu.com/
Log in to the third-party website with account and password
https://oapi.dingtalk.com/connect/oauth2/sns_authorize?appid=xxx&response_type=code&scope=snsapi_login&state=STATE&redirect_uri=https://www.baidu.com/
After successful login in the above two ways, the following effects will be achieved. For the time being, the domain name we use to jump is https://www.baidu.com/ Mainly to obtain temporary code
Obtain user information according to sns temporary authorization code
Through access_token and temporary code to obtain unionid
Preconditions
- You need to set up your own server's exit ip white list on the nailing open platform
Request address
https://oapi.dingtalk.com/sns/getuserinfo_bycode?signature=xxx×tamp=xxx&accessKey=xxx
-
POST
-
query
-
accessKey
In the nailing open platform, the appId of the login application
-
timestamp
Unit: ms
-
signature
The signature algorithm is HmacSHA256, the signature data is the current timestamp, the key is the appSecret corresponding to appId, and the key pair timestamp is used to calculate the signature value.
When sending an HTTP request, you need to urlEncode the signature. If you use the HTTP encapsulation method, please make sure not to repeat urlEncode
-
-
body
{ "tmp_auth_code":"4a2c5695b78738d495f47bxxxxxx" }
response
{ "errcode":0, "user_info":{ "nick":"name", "unionid":"dingdkjjojoixxxx", "openid":"dingsdsqwlklklxxxx", "main_org_auth_high_level":true }, "errmsg":"ok" }
Specific operation and logic of golang
For the signature calculation method of this interface, you need to see how it is implemented. The specific implementation is very simple, but for the value of timestamp, you need to pay attention to the millisecond level
package main import ( "bytes" "crypto/hmac" "crypto/sha256" "crypto/tls" "encoding/base64" "encoding/json" "fmt" "io/ioutil" "net/http" "net/url" "time" ) func main() { // Login app's appSecret secret := "xxxx" key := []byte(secret) h := hmac.New(sha256.New, key) timestamp := time.Now().UnixNano()/1e6 + 120000 //Because my environment time is 2 minutes slower than the nailing server, I added 2 minutes here strTimeStamp := fmt.Sprintf("%d", timestamp) h.Write([]byte(strTimeStamp)) sha := h.Sum(nil) sig := base64.StdEncoding.EncodeToString(sha) mysig := url.QueryEscape(sig) url := fmt.Sprintf("https://oapi.dingtalk.com/sns/getuserinfo_bycode?signature=%s×tamp=%d&accessKey=%s", mysig, timestamp, "xxxx") fmt.Println(url) tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } spaceClient := http.Client{Timeout: time.Second * time.Duration(5), Transport: tr} m := map[string]string{"tmp_auth_code": "67d86cb135ee3bd18d756c2d2fa1a350"} res, err := json.Marshal(m) if err != nil { fmt.Println(res) return } fmt.Println(string(res)) req, err := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(res)) req.Header.Set("Content-Type", "application/json") rawResp, err := spaceClient.Do(req) if err != nil { fmt.Println(rawResp) return } if rawResp.Status != "200 OK" { fmt.Println("rawResp.Status != 200 ok", rawResp) return } body, readErr := ioutil.ReadAll(rawResp.Body) if readErr != nil { fmt.Println("ReadAll error ", readErr) return } fmt.Println("result --", string(body)) }
Get user userid according to unionid
Request address
https://oapi.dingtalk.com/topapi/user/getbyunionid?access_token=xxxxxx
Request method
-
POST
-
query
- access_token
-
body request
{ "unionid":"xxxxxx" }
response
{ "errcode": 0, "errmsg": "ok", "result": { "contact_type": 0, "userid": "managerxxxx" }, "request_id": "xxxxxx" }
Get user details according to userid
Request address
https://oapi.dingtalk.com/topapi/v2/user/get?access_token=xxxxx
Request method
- POST
- query
- access_token
- body request
{ "language":"zh_CN", "userid":"managerxxxxx" }
response
{ "errcode": 0, "errmsg": "ok", "result": { "active": true, "admin": true, "avatar": "", "boss": false, "dept_id_list": [ 1 ], "dept_order_list": [ { "dept_id": 1, "order": 176299320823645512 } ], "email": "", "exclusive_account": false, "hide_mobile": false, "leader_in_dept": [ { "dept_id": 1, "leader": false } ], "mobile": "xxxxx", "name": "xxx", "real_authed": true, "role_list": [ { "group_name": "default", "id": 1993003008, "name": "Master administrator" } ], "senior": false, "state_code": "86", "unionid": "xxxxx", "userid": "managerxxxxx" }, "request_id": "xxxxx" }
Get Department list
Request address
https://oapi.dingtalk.com/topapi/v2/department/listsub?access_token=xxxxx
Request method
- POST
- query
- access_token
- body request
{ "language":"zh_CN", "dept_id":1 }
response
{ "errcode": 0, "errmsg": "ok", "result": [ { "auto_add_user": true, "create_dept_group": true, "dept_id": 477856721, "name": "Operation Department", "parent_id": 1 }, { "auto_add_user": true, "create_dept_group": true, "dept_id": 477856722, "name": "Design Department", "parent_id": 1 } ], "request_id": "evcmse04h8op" }
Get the list of department user userid s
Request address
https://oapi.dingtalk.com/topapi/user/listid?access_token=xxxxxx
Request method
- POST
- query
- access_token
- body request
{ "dept_id":xx }
response
{ "errcode": 0, "errmsg": "ok", "result": { "userid_list": [ "managerxxxxx" ] }, "request_id": "xxxxx" }
Well, that's all for this issue. If it still works for you, please help me to praise and comment. If I can pay attention to it or forward it to your circle of friends, it will be my greatest encouragement
Technology is open, so should our mentality. We embrace change, look to the sun, and unswervingly practice every idea.
Author: Little Devil boy Nezha