# Google Login研究─React & React Native ## Google配置頁面及文件 > 管理憑證和OAuth同意畫面:[Google API Console](https://console.cloud.google.com/) > Google OAuth文件:[Using OAuth 2.0 to Access Google APIs | Authorization | Google Developers](https://developers.google.com/identity/protocols/oauth2) --- ## React (Web App) > - [The guide to adding Google login to your React app | Blog](https://blog.logrocket.com/guide-adding-google-login-react-app/) > - [`@‌react-oauth/google` README | Github](https://github.com/MomenSherif/react-oauth#readme) ### 流程概述 *細節請參考上方第一篇文章連結 - 在[Google API Console](https://console.cloud.google.com/)選擇一專案,設定好「OAuth同意畫面」,這邊的「應用程式名稱」和「使用者者支援電子郵件」會顯示在同意畫面上。 - 呈上,繼續前往憑證頁面,選擇「建立憑證 > OAuth Client ID」,建立供「網頁應用程式」使用的Client ID,下載JSON,在撰寫程式時可以直接使用。 - 上述皆設定完成後使用`npm install @react-oauth/google`,接著完成該套件的配置及程式碼實作。 - 當使用者於同意畫面選擇同意,及代表同意App存取資料,此時App會拿到`access_token`: ```json { "access_token": "ya29.a0Ael9sCPzUXc2CPMDNF2QwG478YRBQFrKHGMRWIQJUNiy8KV9DaBSfk04GvShTLcv7w3zPXSYV-mLz8u3Knl6wFpMEuwKIGSqIswoI7ZPDE_bFkoUEat91CDcx03KfnSfUsj-acyVzqbUH47cbtKXbrkeXyGDaCgYKAeoSARMSFQF4udJhPooiYqwCRQ0ZvLfMLCIxlA0163", "expires_in": 3599, "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ijg2OTY5YWVjMzdhNzc4MGYxODgwNzg3NzU5M2JiYmY4Y2Y1ZGU1Y2UiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJhenAiOiIxMzEyNzg1NDQyNjMtbGlxNmYwdHVhOXVzamUwYzBrMmMxbHVtbjl1YjcxcnAuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJhdWQiOiIxMzEyNzg1NDQyNjMtbGlxNmYwdHVhOXVzamUwYzBrMmMxbHVtbjl1YjcxcnAuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJzdWIiOiIxMDE4NjY5NTkxODAyMzgyMzk5NTciLCJoZCI6Iml0cnVzdG1hY2hpbmVzLmNvbSIsImVtYWlsIjoib2xpdmUud3VAaXRydXN0bWFjaGluZXMuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImF0X2hhc2giOiJYdVhncFdRNDYybG5xTWY4dXVkdVl3IiwibmFtZSI6Ik9saXZlIFd1IiwicGljdHVyZSI6Imh0dHBzOi8vbGgzLmdvb2dsZXVzZXJjb250ZW50LmNvbS9hL0FHTm15eGFQZV9kdU5aUGtDMk0zeHBxd01iUlhVQnAzNDNwZzVsWVViWDJFPXM5Ni1jIiwiZ2l2ZW5fbmFtZSI6Ik9saXZlIiwiZmFtaWx5X25hbWUiOiJXdSIsImxvY2FsZSI6ImVuIiwiaWF0IjoxNjgyNTYzNTQzLCJleHAiOjE2ODI1NjcxNDN9.D7BUSdRcezYHbVf7_-mrCRwjs4CwHDXMFii5hxpXm_u6VoqFTHSU3aweZeqKA2qQIBXXAlBK5zDZkC6RYiojpnfV-JLTAfdsS9x6g3VlMg98jL30rPlWI1_XFsuc7CftXuuECdkXeVnKDYRKsbvr2FWbP_itNS4scLZHiWqv0vPdyaOrzJV-lW7-3nxncp3I1vSOVJjCzT1mrjBdYvjMAT1oGBsqjlHNx-qSleF8jS_6fd9nReXpebI8vckCOgfuu063GOMqi84-CuOFjK-Wb3dXYUwWqg071bRpDiS3rmh8kQAIaCkNGBEEL9ptXXBz0_Y4DCLA1G9UwHqUrRUfJg", "refresh_token": "1//0eyMrbkU5a3u3CgYIARAAGA4SNwF-L9IrhK-GYLhuBOrWaXTxQCoj1ifwYTFZRp9-N2PkJDUD_jqzRAF6N0e-VjEM5wk7jxR-jGc", "scope": "https://www.googleapis.com/auth/userinfo.profile openid https://www.googleapis.com/auth/userinfo.email", "token_type": "Bearer", } ``` *`expires_in`單位為秒數,效期1小時 *`refresh_token`效期為200天 - 透過`access_token`,App可以向Google的Resource Server存取使用者允許的資料: ```json { "id": "101866959180238239957", "email": "olive.wu@itrustmachines.com", "verified_email": true, "name": "Olive Wu", "given_name": "Olive", "family_name": "Wu", "picture": "https://lh3.googleusercontent.com/a/AGNmyxaPe_duNZPkC2M3xpqwMbRXUBp343pg5lYUbX2E=s96-c", "locale": "en", "hd": "itrustmachines.com " } ``` - App可以依照需求提供所需的權限清單(Scope),Authorization Server(即Google)會依照清單尋求使用者的同意。 可以在[Google API Console](https://console.cloud.google.com/)的「OAuth同意畫面 > 範圍」進行Scope設定。 --- ## React Native (Mobile App) > - [Authentication with Google and AuthSession API | Expo](https://docs.expo.dev/guides/google-authentication/) > - [Expo Auth Session - Login with Google in React Native Apps includes Refreshing Tokens and Logout | Youtube](https://www.youtube.com/watch?v=oPTGoJw_Tik&t=2693s&ab_channel=MissCoding) ### 流程概述 *目前只有測試Android功能 - 在[Google API Console](https://console.cloud.google.com/)選擇一專案,設定OAuth同意畫面。 - 至憑證頁面「建立憑證 > OAuth Client ID」,創建供「Android」使用的Client ID,此處需要填寫「套件名稱」及「SHA-1 憑證指紋」。 1. 填寫`app.json`中`android.package`的package name,若沒有則新增於檔案中。若選擇建立iOS的Client ID請在`ios.bundleIdentifier`下新增。 ```json { "expo": { "android": { "package": "com.test.google", } }, } ``` 2. 取得SHA-1 憑證指紋: - `npm install -g eas-cli` - 執行`eas build:configure`並選擇"ALL"以產生`eas.json`。 - 執行`eas credentials -p android`並follow[此章節](https://docs.expo.dev/guides/google-authentication#create-client-ids)的SHA-1 certificate fingerprint步驟。 - 完成後複製SHA1 Fingerprint至憑證頁面貼上。 - 完成[AuthSession API相關配置及實作](https://docs.expo.dev/guides/google-authentication#using-authsession-api)。 - 使用者在手機App上點選登入按鈕,會在App中開啟內建瀏覽器(WebView)顯示同意畫面。 使用者同意存取後會返回App,且App會取得`accessToken`以向Google拿取使用者資料。 ```json { "type": "success", "error": null, "url": "exp://192.168.30.137:19000/--/expo-auth-session#state=6icSHYQq1Z&access_token=ya29.a0Ael9sCOgPNMti67vlIskLeCPhb3v22RvcIvKJ2auhN4Huz2Xv5OITshRwQ2DAdVbzqZtmYD4fKx9Q6fvSHAcEUBfTnUQow4qNPaxU9Ej_Cx7JBOrkeqFslPVZX5j2TIZ1pGbfgZJAmmu00tL4_C-YYOJWDlNaCgYKAX8SARMSFQF4udJhYhSwwmWznZ0xDIWeIpIGYQ0163&token_type=Bearer&expires_in=3599&scope=email%20profile%20openid%20https://www.googleapis.com/auth/userinfo.profile%20https://www.googleapis.com/auth/userinfo.email&authuser=1&hd=itrustmachines.com&prompt=none", "params": { "exp://192.168.30.137:19000/--/expo-auth-session": "", "state": "6icSHYQq1Z", "access_token": "ya29.a0Ael9sCOgPNMti67vlIskLeCPhb3v22RvcIvKJ2auhN4Huz2Xv5OITshRwQ2DAdVbzqZtmYD4fKx9Q6fvSHAcEUBfTnUQow4qNPaxU9Ej_Cx7JBOrkeqFslPVZX5j2TIZ1pGbfgZJAmmu00tL4_C-YYOJWDlNaCgYKAX8SARMSFQF4udJhYhSwwmWznZ0xDIWeIpIGYQ0163", "token_type": "Bearer", "expires_in": "3599", "scope": "email profile openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email", "authuser": "1", "hd": "itrustmachines.com", "prompt": "none" }, "authentication": { "accessToken": "ya29.a0Ael9sCOgPNMti67vlIskLeCPhb3v22RvcIvKJ2auhN4Huz2Xv5OITshRwQ2DAdVbzqZtmYD4fKx9Q6fvSHAcEUBfTnUQow4qNPaxU9Ej_Cx7JBOrkeqFslPVZX5j2TIZ1pGbfgZJAmmu00tL4_C-YYOJWDlNaCgYKAX8SARMSFQF4udJhYhSwwmWznZ0xDIWeIpIGYQ0163", "tokenType": "Bearer", "expiresIn": "3599", "scope": "email profile openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email", "state": "6icSHYQq1Z", "issuedAt": 1682490920 }, "errorCode": null } ``` - 使用[Development builds](https://docs.expo.dev/develop/development-builds/introduction/?redirected)運行,並且在程式碼中的`promptAsync()`設定`{ useProxy: false }`: ```javascript const [request, response, promptAsync] = Google.useAuthRequest(googleConfig) ... return ( <Button title="Sign in with Google" disabled={!request} onPress={() => { promptAsync({ useProxy: false }) }} /> ) ``` 在使用Google OAuth功能時,便不會另外導轉至該頁面。 ![](https://i.imgur.com/AtKNag4.png) --- ## 補充 - [Google API Console](https://console.cloud.google.com/) > 「OAuth同意畫面」 發布狀態為「測試中」時,需要將測試使用者加入清單才能進行測試,且上限為100人。 ![](https://i.imgur.com/h2vNYds.png) - #### [Security considerations](https://docs.expo.dev/versions/latest/sdk/auth-session#security-considerations) **Never put any secret keys inside of your application code**, there is no secure way to do this! Instead, you should store your secret key(s) on a server and expose an endpoint that makes API calls for your client and passes the data back.