Contents

Google登入-Google SDK API

Google登入-Google SDK API

這篇主要是Google SDK API的登入驗證,和Facebook提供的SDK差不多,都是複製貼上就可以動的優良程式!,唯一比較大的缺點是,改版速度太快,文件又多又雜,且幾乎是英文文件,散落於各處,很容易困惑到底該使用哪個API服務…,友善提醒,Google官網改版很快,申請畫面不同很正常。

建立應用程式服務

  1. Google Cloud Platform 申請建立應用程式

    /static/Google_Google_SDK_API_1fd14ec6524242769adde360da81c914/2020-09-24_15-03-33.png
  2. 選擇網頁應用程式,使用Javascript SDK,填入已授權的 JavaScript 來源及已授權的重新導向 URI,使用Javascript SDK重新導向網址在可以不填,不過我在另一篇中有用到這項,所以圖示上還是填寫了,這邊會特別講是因為,那個回傳網址,強烈建議不要更動,也就是使用/signin-google,這組,可以省掉很多很多的問題…

    /static/Google_Google_SDK_API_1fd14ec6524242769adde360da81c914/2020-09-24_16-29-55.png
  3. 建立完成後,就可以看到用戶端ID和用戶端密碼,這兩項等等要輸入到SDK中,畫面關掉也沒關係,外面也可以找到

    /static/Google_Google_SDK_API_1fd14ec6524242769adde360da81c914/2020-09-24_15-16-06.png
  4. 如果只是要登入的部分,這邊就結束了,如果要取得使用者資料,則需要再申請API服務,可以取得使用者資料的API很多 微軟使用的是 https://www.googleapis.com/oauth2/v2/userinfo 而Google Javascript SDK範例是使用 Google People API,不清楚差異,但我們只要ID、Name、Email,擇一即可 點資料庫,選擇 Google People API 並啟用

    /static/Google_Google_SDK_API_1fd14ec6524242769adde360da81c914/2020-09-24_15-38-10.png
  5. Google People API啟用後,我們就要申請一組API Key,有這組Key,API才可以正常使用,Google API 服務與Key是分開的,一組Key可以多組服務,也可以一組Key對應一組服務,另外Google會提醒你配額問題,可能有部分的API服務會計費,詳細請自行查看Google配額說明,這邊不詳細介紹。

    /static/Google_Google_SDK_API_1fd14ec6524242769adde360da81c914/2020-09-24_15-46-43.png /static/Google_Google_SDK_API_1fd14ec6524242769adde360da81c914/2020-09-24_15-47-14.png

    應用程式建立到這邊基本流程就結束了,Google API服務、憑證、Key三者都是分開申請的,所以申請順序沒有太大差異,如果參照其他Blog發現順序好像不一樣,是很正常的,簡而言之,只要你有申請這三項應該都可以正常執行。

實作

Google SDK API,有提供GitHub連結,範例程式碼照貼即可運作,記得填寫自己的API KEY及申請的用戶端ID,我直接將幾個重點標註在程式碼中

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<p>Say hello using the People API.</p>

<button id="authorize-button" style="display: none;">Authorize</button>
<button id="signout-button" style="display: none;">Sign Out</button>

<div id="content"></div>

<script type="text/javascript">

		// 這邊就是你剛剛申請的API KEY
    var apiKey = '{API KEY}';
    var discoveryDocs = ["https://people.googleapis.com/$discovery/rest?version=v1"];
		
		// 用戶端ID
    var clientId = '{用戶端ID}';
		
		// 這邊是應用程式申請可讀取的範圍,每種服務API不一樣
		// People API範圍請參考
		// https://developers.google.com/people/v1/how-tos/authorizing#OAuth2Authorizing
    var scopes = 'profile';

    var authorizeButton = document.getElementById('authorize-button');
    var signoutButton = document.getElementById('signout-button');

    function handleClientLoad() {
        gapi.load('client:auth2', initClient);
    }

    function initClient() {
        gapi.client.init({
            apiKey: apiKey,
            discoveryDocs: discoveryDocs,
            clientId: clientId,
            scope: scopes
        }).then(function () {
            gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);

            updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());

            authorizeButton.onclick = handleAuthClick;
            signoutButton.onclick = handleSignoutClick;
        });
    }

    function updateSigninStatus(isSignedIn) {
        if (isSignedIn) {
            authorizeButton.style.display = 'none';
            signoutButton.style.display = 'block';
            makeApiCall();
        } else {
            authorizeButton.style.display = 'block';
            signoutButton.style.display = 'none';
        }
    }

    function handleAuthClick(event) {
        // 官方範例到這邊為止,但若是Server端要取得用戶資料,則需再使用id_Token,傳送至Server端進行驗證
        gapi.auth2.getAuthInstance().signIn()
            .then(function (googleUser) {
                let id_token = googleUser.getAuthResponse().id_token;
                postToken(id_token);
            });
    }

    function postToken(id_token) {
        let url = '/Login/LoginProcess';
        $.ajax({
            url: url,
            method: 'POST',
            data: { token: id_token },
        });
    }

    function handleSignoutClick(event) {
        gapi.auth2.getAuthInstance().signOut();
    }

    function makeApiCall() {
        gapi.client.people.people.get({
            'resourceName': 'people/me',
            'requestMask.includeField': 'person.names'
        }).then(function (resp) {
            var p = document.createElement('p');
            var name = resp.result.names[0].givenName;
            p.appendChild(document.createTextNode('Hello, ' + name + '!'));
            document.getElementById('content').appendChild(p);
        });
    }
</script>
<script async defer src="https://apis.google.com/js/api.js"
        onload="this.onload=function(){};handleClientLoad()"
        onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>

將IdToken傳送到Server端後,透過 Nuget > System.IdentityModel.Tokens.Jwt 取得資料

/static/Google_Google_SDK_API_1fd14ec6524242769adde360da81c914/2020-09-15_13-33-27.png /static/Google_Google_SDK_API_1fd14ec6524242769adde360da81c914/2020-09-15_11-54-59.png

或是透過Google API,取得客戶資料

/static/Google_Google_SDK_API_1fd14ec6524242769adde360da81c914/_2020-09-15_134840.png

Server端程式碼

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
[HttpPost]
public async Task<IActionResult> LoginProcess(string token)
{
    // Nuget套件 System.IdentityModel.Tokens.Jwt
    var user = new System.IdentityModel.Tokens.Jwt.JwtSecurityToken(token);

    // 除此之外,也可以透過Google API 取得
    var url = $"https://oauth2.googleapis.com/tokeninfo?id_token={token}";
    var client = _clientFactory.CreateClient();
    var response = await client.GetAsync(url);
    if (response.IsSuccessStatusCode)
    {
        var responseContent = await response.Content.ReadAsStringAsync();
        // 略...
    }

    return View();
}

參考

Javascript SDK API Github

https://github.com/google/google-api-javascript-client

People API Scope

https://developers.google.com/people/v1/how-tos/authorizing#OAuth2Authorizing

Google Authenticate with a backend server

https://developers.google.com/identity/sign-in/web/backend-auth

高級打字員的技術雲 Blog

https://dotblogs.com.tw/shadow/2019/10/11/030306