專案準備
首先當然是要先有個Ionic&Capacitor的專案,專案的建置之前的文章有示範如何建立可以【點我前往】參考,範例程式碼的css都會使用Tailwind有需要的人可以自行前往安裝【點我前往】接著下面所有的OAuth2.0流程我會使用第三方的開源套件作為示範【點我前往Github】,使用以下指令安裝套件
npm i @byteowls/capacitor-oauth2
再來就是準備一個可以互動的畫面和社交登入按鈕
<button
class="mt-5 w-full bg-white text-gray-700 hover:bg-gradient-to-r hover:from-blue-600 hover:to-indigo-600 hover:text-white focus:outline-none focus:shadow-outline"
type="button" (click)="onGoogleLoginClick()">
<div class="rounded border border-gray-300 flex flex-row items-center justify-center py-2 px-4">
<img src="assets/icon/google-login-icon.svg" width="24" height="24" class="mr-2" />
<span class="text-sm font-bold">使用 Google 帳戶登入</span>
</div>
</button>
<button
class="mt-5 w-full bg-white text-gray-700 hover:bg-gradient-to-r hover:from-blue-600 hover:to-indigo-600 hover:text-white focus:outline-none focus:shadow-outline"
type="button" (click)="onMicrosoftLoginClick()">
<div class="rounded border border-gray-300 flex flex-row items-center justify-center py-2 px-4">
<img src="assets/icon/microsoft-login-icon.svg" width="24" height="24" class="mr-2" />
<span class="text-sm font-bold">使用 Microsoft 帳戶登入</span>
</div>
</button>
OAuth設定 - Google
在應用程式類型中,我們要建立兩個,一個是「網頁應用程式」,另一個是「Android」,這兩個設定的方式不一樣因此我會分開來介紹。
💡 由於我多數時間還是會用Web的方式去開發Ionic&Capacitor的應用程式,因此才會把網頁應用程式也納入設定的範圍內
網頁應用程式
Android
而SHA-1憑證指紋則是需要從keystore計算得來的,我們可以使用以下指令找到SHA-1
keytool -list -v -keystore %HOMEPATH%/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android
💡 keytool工具只要安裝Java JDK就會有
💡 這裡我們使用keystore是開發環境的debug.keystore,生產環境下記得替換成正確的keystore哦!
💡 如果在Windows上,這段指令不適合執行在PowerShell上哦!
OAuth設定 - Microsoft
微軟的應用程式設定可以參考我之前寫的文章【點我前往】,這裡我會直接針對不一樣的地方做說明。
接著到找到左側選單「驗證」→「平台設定」→「新增平台」,這裡一樣新增兩個平台「單頁應用程式」和「Android」單頁應用程式
單頁應用程式(SPA)通常使用隱式授權流程(Implicit Grant Flow)或授權代碼流程與 PKCE (Proof Key for Code Exchange)。這些流程都是在前端JavaScript代碼中執行的,並且直接返回到應用程式的安全令牌,我們專案是Ionic基於Angular因此也是一個SPA。相反,Web應用程式通常使用授權代碼流程(Authorization Code Grant Flow),該流程涉及到後端伺服器,並且會將授權代碼返回到後端,然後後端會換取安全令牌,所以這兩個在授權的流程上會有點不同哦!Android
而Android上的設定跟Google一樣需要提供「套件名稱」,而這裡的簽章雜湊就不同於Google,它是把SHA-1轉成二進制後再Base64編碼,因此指令上也會有些許不同,我們使用以下命令
keytool -exportcert -alias androiddebugkey -keystore %HOMEPATH%\.android\debug.keystore | openssl sha1 -binary | openssl base64
💡 這裡需要OpenSSL的工具,可以【點我前往】安裝
Social Login
講了這麼多終於來到這篇的主題了XD,接下來就照著Github上面寫的建立Google和Microsoft的「OAuth2AuthenticateOptions」的物件吧!
在Github提供的Google OAuth2AuthenticateOptions設定中的Scope需要加入「openid」,另外在web屬性下的responseType的地方我們需要多加一個「id_Token」 才可以正確取得OpenID哦!
private getGoogleOAuth2Options(): OAuth2AuthenticateOptions {
return {
authorizationBaseUrl: 'https://accounts.google.com/o/oauth2/auth',
accessTokenEndpoint: "https://www.googleapis.com/oauth2/v4/token",
scope: "email profile openid",
resourceUrl: "https://www.googleapis.com/userinfo/v2/me",
logsEnabled: true,
web: {
appId: 'Your Google Client Id',
responseType: 'id_token token', // implicit flow
accessTokenEndpoint: '', // clear the tokenEndpoint as we know that implicit flow gets the accessToken from the authorizationRequest
redirectUrl: "http://localhost:8100",
windowOptions: "width=500,height=600"
},
android: {
appId: 'Your Google Client Id',
responseType: "code", // if you configured a android app in google dev console the value must be "code"
redirectUrl: "sociallogin.test.app:/" // package name from google dev console
},
ios: {
appId: 'Your Google Client Id',
responseType: "code", // if you configured a ios app in google dev console the value must be "code"
redirectUrl: "sociallogin.test.app:/" // Bundle ID from google dev console
}
};
}
💡 在google的web屬性中請不要使用responseType=code,由於web的驗證流程都在前端Javascript上執行,code流程本身是需要Client Secret(你也不會希望把你的Client Secret放到JavaScrip上吧XD),OAuth2AuthenticateOptions物件本身也沒有地方給你設定Client Secret,另外就算打開PKCE的驗證方式也是無法通過Token驗證(可能是Google不提供PKCE的流程)哦!
💡 開發階段可以把logsEnabled打開,可以在Console看到跑了哪些流程,有助於自己理解OAuth的過程哦!
Microsoft
而Github提供的Microsoft OAuth2AuthenticateOptions設定也是在Scope屬性多加「openid」,其餘的都不用改哦!private getAzureB2cOAuth2Options(): OAuth2AuthenticateOptions {
return {
appId: 'Your Microsoft Client Id',
authorizationBaseUrl: 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize',
scope: 'https://graph.microsoft.com/.default openid',
accessTokenEndpoint: 'https://login.microsoftonline.com/common/oauth2/v2.0/token',
resourceUrl: "https://graph.microsoft.com/v1.0/me/",
responseType: "code",
pkceEnabled: true,
logsEnabled: true,
web: {
redirectUrl: 'http://localhost:8100',
windowOptions: "width=500,height=600",
},
android: {
redirectUrl: "msauth://sociallogin.test.app/URKPrDTU8V1MeU...." // See Azure Portal -> Authentication -> Android Configuration "Redirect URI"
},
ios: {
pkceEnabled: true, // workaround for bug #111
redirectUrl: "msauth.{package-name}://auth"
}
};
}
💡 Microsoft只能設定responseType=code,並且搭配PKCE做驗證哦!
最後在ButtonOnClick的地方呼叫OAuth2Client.authenticate就完成囉!
onMicrosoftLoginClick() {
OAuth2Client.authenticate(
this.getAzureB2cOAuth2Options()
).then(result => console.log(result));
}
onGoogleLoginClick() {
OAuth2Client.authenticate(
this.getGoogleOAuth2Options()
).then(result => console.log(result));
}
總結
在這篇我們利用開源的第三方套件Capacitor OAuth2.0實作了OpenID Connect的SSO登入,實際上OpenID Connect本身也是從OAuth2.0去做設計的,因此實作時就跟OAuth幾乎一模一樣呢XD,另外OpenID Connect還有其它的流程可以參考,每一個流程在執行上都有些微的不同,在Github有提供一個網址介紹這些流程我覺得講的很清楚,有興趣的可以【點我前往】參考看看哦!
0 Comments
張貼留言