{{announcement.body}}
{{announcement.title}}

Account Binding for Card Ability (Part 2)

DZone 's Guide to

Account Binding for Card Ability (Part 2)

In this part, we are going to create a relation between the user Id and his open ID to send the Account Binding Result Notification to Huawei.

· Integration Zone ·
Free Resource

In part 1 we have configured the server to receive the account binding request from the card ability and the app to receive an anonymized open ID to perform the authentication with your server, in this part, we are going to create a relation between the user Id and his open ID to send the Account Binding Result Notification to Huawei.

Note: The User Id is the unique identifier that you have defined for a specific user in your account system, for example, the email address.

Sending the Account Information

When the user logins successfully in your app or are agree to continue using the registered account the app must send the user information to your server so you can create a relation between the User Id and his open Id.

Java
 




x
35


 
1
try {
2
 
          
3
     URL url=new URL("LINK_TO_YOUR_SERVER");
4
 
          
5
     HttpURLConnection conn=(HttpURLConnection) url.openConnection();
6
 
          
7
     conn.setRequestMethod("POST");
8
 
          
9
     JSONObject object=new JSONObject();
10
 
          
11
     object.put("openId", openId);
12
 
          
13
     object.put("uid",uid);
14
 
          
15
     OutputStream os=conn.getOutputStream();
16
 
          
17
     os.write(object.toString().getBytes());
18
 
          
19
     os.flush();
20
 
          
21
 } catch (MalformedURLException e) {
22
 
          
23
     e.printStackTrace();
24
 
          
25
 } catch (IOException e) {
26
 
          
27
     e.printStackTrace();
28
 
          
29
 } catch (JSONException e) {
30
 
          
31
     e.printStackTrace();
32
 
          
33
 }
34
 
          
35
 
          



Associating the User’s Id With This Open Id

From your server-side, once you receive the user information you must store it into your database and send an Account Binding Result Notification, so the Huawei server can know the Account Binding process is complete.

Java
 







Obtaining the App Level Access Token

To send the notification to Huawei you must first apply for an access token using the App Id and App Secret of your card RPK package to authenticate your server with the Huawei Server. You can find your App Id and secret from your project page in AGC.

To obtain the App Level Access Token, send a POST request to the Huawei’s OAUTH server.

Hostname: oauth-login.cloud.huawei.com

Path: /oauth2/v2/token

Headers:

  • Content-Type: application/x-www-form-urlencoded

Body: "grant_type=client_credetials" + "&client_id=" + APP_ID + "&client_secret=" + APP_SECRET (in URL encode).

You can get the App Id and App Secret from the app overview of your card in App Gallery Connect.

The next is a sample using an AWS lambda function:

Java
 




xxxxxxxxxx
1
137


 
1
const https=require("https")
2
 
          
3
exports.handler = async(event,context) => {
4
 
          
5
    // TODO implement
6
 
          
7
    
8
 
          
9
    const grant_type = encodeURI("client_credentials");
10
 
          
11
    var client_id;
12
 
          
13
     
14
 
          
15
    if(event.hasOwnProperty('appId')){
16
 
          
17
      client_id=encodeURI(event.appId);
18
 
          
19
    }
20
 
          
21
    else{
22
 
          
23
      client_id=encodeURI(process.env.appId);
24
 
          
25
    }
26
 
          
27
     
28
 
          
29
    var client_secret;
30
 
          
31
    if(event.hasOwnProperty('appSecret')){
32
 
          
33
      client_secret=encodeURI(event.appSecret);
34
 
          
35
    }
36
 
          
37
    else{
38
 
          
39
      client_secret=encodeURI(process.env.appSecret);
40
 
          
41
    }
42
 
          
43
  
44
 
          
45
    const data = "grant_type=" + grant_type + "&client_id=" + client_id + "&client_secret=" + client_secret;
46
 
          
47
    console.log(data);
48
 
          
49
   
50
 
          
51
    try{
52
 
          
53
      const result= await getAccessToken(data);
54
 
          
55
      console.log(result);
56
 
          
57
      const json=JSON.parse(result);
58
 
          
59
      return json;
60
 
          
61
    }catch(error){
62
 
          
63
      context.fail(error);
64
 
          
65
    }
66
 
          
67
};
68
 
          
69
const getAccessToken = (data) => {
70
 
          
71
//    https://login.cloud.huawei.com/oauth2/v2/token
72
 
          
73
  
74
 
          
75
  return new Promise((resolve, reject) => {
76
 
          
77
    //https://oauth-login.cloud.huawei.com/oauth2/v2/token
78
 
          
79
    //login.cloud.huawei.com
80
 
          
81
    const options = {
82
 
          
83
        hostname:'oauth-login.cloud.huawei.com',
84
 
          
85
        path'/oauth2/v2/token',
86
 
          
87
        method'POST',
88
 
          
89
        headers: {
90
 
          
91
            'Content-Type''application/x-www-form-urlencoded'
92
 
          
93
        }
94
 
          
95
    };
96
 
          
97
  
98
 
          
99
    //create the request object with the callback with the result
100
 
          
101
    const req =https.request(optionsfunction(res) {
102
 
          
103
      res.setEncoding('utf8');
104
 
          
105
      res.on('data'function (chunk) {
106
 
          
107
          resolve(chunk);
108
 
          
109
           
110
 
          
111
      });
112
 
          
113
      res.on('error'function (e) {
114
 
          
115
        reject(e.message);
116
 
          
117
      });
118
 
          
119
  
120
 
          
121
  });
122
 
          
123
    //do the request
124
 
          
125
    req.write(data);
126
 
          
127
  
128
 
          
129
    //finish the request
130
 
          
131
    req.end();
132
 
          
133
  });
134
 
          
135
};
136
 
          
137
 
          



Sending the Account Binding Result Notification

Use the anonymized Open Id from the user’s request to find the real Open Id and send it to the Huawei Server.

Hostname:

  • Europe: hag-eu.cloud.huawei.com

  • Russia: hag-ru.cloud.huawei.com

  • AALA: hag-sg.cloud.huawei.com

Path: /open-ability/v1/open-account-events/bind

Headers:

  • Content-Type: “application/JSON”

  • Accept: “application/JSON”

  • x-appid: The card’s app id

  • Authorization: Bearer + App Level Access Token

Body: 

  • requestTime: UTC request time

  • openId: Open Id of the user.

Java
 




xxxxxxxxxx
1
137


 
1
'use strict'
2
const AWS = require('aws-sdk');
3
AWS.config.update({ region"us-east-2" });
4
  
5
exports.handler = async(event, context) => {
6
    //Get App Level AT
7
    var payload = {
8
        appId: event.appId,
9
        appSecret: event.appSecret
10
    };
11
    var accessToken;
12
    try {
13
        accessToken = await getAppLevelAccessToken(payload);
14
    }
15
    catch (err) {
16
        context.fail(err);
17
    }
18
     
19
    var options=getOptions(accessToken,event.appId,event.type);
20
    var body = getRequestObject(event.openId);
21
    try {
22
        const result = await doPostRequest(options, JSON.stringify(body));
23
        console.log(result);
24
        return result;
25
    }
26
    catch (e) {
27
        console.log(e);
28
        context.fail(e);
29
    }
30
    //Send the response of the excecution
31
    const response = {
32
        statusCode: 200,
33
        body: JSON.stringify('Success'),
34
    };
35
    return response;
36
};
37
  
38
function getOptions(accessToken,appId,type){
39
    //Send the obj as an Account Binding Result Notification
40
    const auth = "Bearer " + encodeURI(accessToken);
41
    const options = {
42
        hostname'hag-sg.cloud.huawei.com',
43
        path'/open-ability/v1/open-account-events/bind',
44
        method'POST',
45
        headers: {
46
            'Content-Type''application/json',
47
            'Accept''application/json',
48
            'x-appid': appId,
49
            'Authorization': auth
50
        }
51
    };
52
    console.log(options);
53
    return options;
54
}
55
  
56
function getRequestObject(openId) {
57
    const time = new Date(new Date().toUTCString());
58
    const utc = time.YYYYMMDDHHMMSS();
59
    var obj = {
60
        "requestTime": utc,
61
        "openId": openId
62
    };
63
    return obj;
64
}
65
  
66
Date.prototype.YYYYMMDDHHMMSS = function() {
67
    var yyyy = this.getFullYear().toString();
68
    var MM = pad(this.getMonth() + 1, 2);
69
    var dd = pad(this.getDate(), 2);
70
    var hh = pad(this.getHours(), 2);
71
    var mm = pad(this.getMinutes(), 2);
72
    var ss = pad(this.getSeconds(), 2);
73
    var sss = pad(this.getMilliseconds(), 3);
74
  
75
    return yyyy + MM + dd + hh + mm + ss + sss;
76
};
77
  
78
function pad(number, length) {
79
  
80
    var str = '' + number;
81
    while (str.length < length) {
82
        str = '0' + str;
83
    }
84
  
85
    return str;
86
  
87
}
88
const getAppLevelAccessToken = (payload) => {
89
    var params = {
90
        FunctionName'GetAccessToken'// the lambda function we are going to invoke
91
        InvocationType'RequestResponse',
92
        LogType'Tail',
93
        Payload: JSON.stringify(payload)
94
    };
95
    return new Promise((resolve, reject) => {
96
        //Get App Level Access Token
97
        var lambda = new AWS.Lambda();
98
        lambda.invoke(paramsfunction(err, data) {
99
            if (err) {
100
                reject(err);
101
            }
102
            else {
103
                const payload = JSON.parse(data.Payload);
104
                console.log(data.Payload)
105
                resolve(payload.access_token);
106
            }
107
        });
108
    });
109
};
110
  
111
const doPostRequest = (options, body) => {
112
    const https = require("https");
113
    return new Promise((resolve, reject) => {
114
        //create the request object with the callback with the result
115
        const req = https.request(optionsfunction(res) {
116
            res.setEncoding('utf8');
117
            console.log(res.statusCode);
118
            res.on('data'function(chunk) {
119
                console.log('Response: ' + chunk);
120
                resolve(chunk);
121
  
122
            });
123
            res.on('error'function(e) {
124
                console.log(e.message);
125
                reject(e.message);
126
            });
127
  
128
        });
129
        //do the request
130
        if(body){
131
            req.write(body);
132
        }
133
  
134
        //finish the request
135
        req.end();
136
    });
137
};



If you get a response code 200 from Huawei, the Account Binding process is complete.

Account Unbinding

The user can unbind his account at any time. When this happens, Huawei will send a request to the Host you’ve configured for account binding, but the body will include a “deauthorization” in the body.header.namespace

Java
 




xxxxxxxxxx
1
41


 
1
{
2
 
          
3
    "version""1.0",
4
 
          
5
    "header": {
6
 
          
7
        "type""Directive",
8
 
          
9
        "timestamp""1591977828057",
10
 
          
11
        "name""AcceptGrant",
12
 
          
13
        "namespace""Deauthorization"
14
 
          
15
    },
16
 
          
17
    "inquire": {
18
 
          
19
        "inquireId""efd1f6ca-8fdf-11e8-9eb6-529269fb1459",
20
 
          
21
        "payload": {
22
 
          
23
            "grant": {
24
 
          
25
                "type""OAuth2.Authorization",
26
 
          
27
                "openId""the user’s openId",
28
 
          
29
                "sign""A/rD2kV2GT08F+K7Q2WnvZL0jQoxISbQWhlo8GhtRHc=",
30
 
          
31
                "abilityId""7a0af511a91f4591b4efbbaacd8bee60"
32
 
          
33
            }
34
 
          
35
        }
36
 
          
37
    }
38
 
          
39
}
40
 
          
41
 
          



When you receive this request you must delete the user’s Open Id from your database and send an Account Unbinding Result Notification. The API definition of the unbinding process is the same as for the Account Binding, just change the path. You can use the next function to obtain the bind/unbind request, setting the “type” param to bind/unbind.

Java
 




xxxxxxxxxx
1
33


 
1
function getOptions(accessToken,appId,type){
2
 
          
3
    //Send the obj as an Account Binding Result Notification
4
 
          
5
    const auth = "Bearer " + encodeURI(accessToken);
6
 
          
7
    const options = {
8
 
          
9
        hostname'hag-sg.cloud.huawei.com',
10
 
          
11
        path'/open-ability/v1/open-account-events/'+type,
12
 
          
13
        method'POST',
14
 
          
15
        headers: {
16
 
          
17
            'Content-Type''application/json',
18
 
          
19
            'Accept''application/json',
20
 
          
21
            'x-appid': appId,
22
 
          
23
            'Authorization': auth
24
 
          
25
        }
26
 
          
27
    };
28
 
          
29
    console.log(options);
30
 
          
31
    return options;
32
 
          
33
}



Conclusion

Now you know how to make the Account Bind/Unbind for your card ability. The next step is using the user’s Open Id to send a Push Event.

Reference

Official documentation

Topics:
android, application, integration, mobile, opensource, tutorial

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}