Skip to content

Commit

Permalink
feat: Use PKCE to obtain token. (#3)
Browse files Browse the repository at this point in the history
* feat: Use PKCE to obtain access_token.

* fix: remove clientSecret in test file.

* fix remove chinese comments.
  • Loading branch information
cwp0 authored Sep 27, 2023
1 parent edd4b40 commit a75a901
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 15 deletions.
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ Initialization requires 7 parameters, which are all string type:
| ---------------- | ---- | --------------------------------------------------- |
| serverUrl | Yes | your Casdoor server URL |
| clientId | Yes | the Client ID of your Casdoor application|
|clientSecret|Yes|the Client Secret of your Casdoor application|
| appName | Yes | the name of your Casdoor application |
| organizationName | Yes | the name of the Casdoor organization connected with your Casdoor application |
| redirectPath | No | the path of the redirect URL for your Casdoor application, will be `/callback` if not provided |
Expand All @@ -53,7 +52,6 @@ import SDK from 'casdoor-react-native-sdk'
const sdkConfig = {
serverUrl: 'https://door.casdoor.com',
clientId: 'b800a86702dd4d29ec4d',
clientSecret: '1219843a8db4695155699be3a67f10796f2ec1d5',
appName: 'app-example',
organizationName: 'casbin',
redirectPath: 'http://localhost:5000/callback',
Expand All @@ -75,7 +73,6 @@ Initialization parameters are consistent with the previous node.js section:
const sdkConfig = {
serverUrl: 'https://door.casdoor.com',
clientId: 'b800a86702dd4d29ec4d',
clientSecret: '1219843a8db4695155699be3a67f10796f2ec1d5',
appName: 'app-example',
organizationName: 'casbin',
redirectPath: 'http://localhost:5000/callback',
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
"homepage": "https://github.com/casdoor/casdoor-react-native-sdk",
"dependencies": {
"@react-native-async-storage/async-storage": "^1.19.3",
"jwt-decode": "^3.1.2"
"jwt-decode": "^3.1.2",
"react-native-pkce-challenge": "^5.2.0"
}
}
19 changes: 12 additions & 7 deletions src/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@

import AsyncStorage from '@react-native-async-storage/async-storage';
import jwtDecode from 'jwt-decode';
import pkceChallenge from 'react-native-pkce-challenge'

export interface SdkConfig {
serverUrl: string, // your Casdoor server URL, e.g., 'https://door.casdoor.com' for the official demo site
clientId: string, // the Client ID of your Casdoor application, e.g., 'b800a86702dd4d29ec4d'
clientSecret: string, // the Client Secret of your Casdoor application, e.g., '1219843a8db4695155699be3a67f10796f2ec1d5'
appName: string, // the name of your Casdoor application, e.g., 'app-example'
organizationName: string // the name of the Casdoor organization connected with your Casdoor application, e.g., 'casbin'
redirectPath?: string // the path of the redirect URL for your Casdoor application, will be 'http://localhost:5000/callback' if not provided
Expand All @@ -44,6 +44,7 @@ export interface Account {

class Sdk {
private config: SdkConfig
private pkce = pkceChallenge();

constructor(config: SdkConfig) {
this.config = config
Expand Down Expand Up @@ -81,7 +82,7 @@ class Sdk {
const redirectUri = this.config.redirectPath && this.config.redirectPath.includes('://') ? this.config.redirectPath : `${window.location.origin}${this.config.redirectPath}`;
const scope = 'read';
const state = await this.getOrSaveState();
return `${this.config.serverUrl.trim()}/login/oauth/authorize?client_id=${this.config.clientId}&response_type=code&redirect_uri=${encodeURIComponent(redirectUri)}&scope=${scope}&state=${state}`;
return `${this.config.serverUrl.trim()}/login/oauth/authorize?client_id=${this.config.clientId}&response_type=code&redirect_uri=${encodeURIComponent(redirectUri)}&scope=${scope}&state=${state}&code_challenge=${this.pkce.codeChallenge}&code_challenge_method=S256`;
}

public getUserProfileUrl(userName: string, account: Account): string {
Expand Down Expand Up @@ -119,11 +120,15 @@ class Sdk {
const state = redirectUrl.substring(stateStartIndex);
await AsyncStorage.setItem('casdoor-state', state);
try {
const response = await fetch(`${this.config.serverUrl}/api/login/oauth/access_token?client_id=${this.config.clientId}&client_secret=${this.config.clientSecret}&grant_type=authorization_code&code=${code}`,
{
method: 'POST',
credentials: 'include',
});
const response = await fetch(`${this.config.serverUrl.trim()}/api/login/oauth/access_token`, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
// @ts-ignore
body: `client_id=${this.config.clientId}&grant_type=authorization_code&code=${code}&redirect_uri=${encodeURIComponent(this.config.redirectPath)}&code_verifier=${this.pkce.codeVerifier}`,
credentials: 'include',
});
if (response.ok) {
const responseData = await response.json();
const token = responseData.access_token;
Expand Down
6 changes: 2 additions & 4 deletions test/sdk.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import AsyncStorage from '@react-native-async-storage/async-storage';
const sdkConfig = {
serverUrl: 'https://door.casdoor.com',
clientId: 'b800a86702dd4d29ec4d',
clientSecret: '1219843a8db4695155699be3a67f10796f2ec1d5',
appName: 'app-example',
organizationName: 'casbin',
redirectPath: 'http://localhost:5000/callback',
Expand All @@ -18,7 +17,6 @@ describe('sdk constructor', () => {
const instanceConfig = sdk['config'];
expect(instanceConfig.serverUrl).toEqual(sdkConfig.serverUrl);
expect(instanceConfig.clientId).toEqual(sdkConfig.clientId);
expect(instanceConfig.clientSecret).toEqual(sdkConfig.clientSecret);
expect(instanceConfig.appName).toEqual(sdkConfig.appName);
expect(instanceConfig.organizationName).toEqual(sdkConfig.organizationName);
expect(instanceConfig.redirectPath).toEqual(sdkConfig.redirectPath);
Expand Down Expand Up @@ -61,7 +59,7 @@ describe('getSigninUrl', () => {

it('with fixed state', async () => {
const state = 'test-state';
await AsyncStorage.setItem('casdoor-state', state); // 使用await等待异步操作完成
await AsyncStorage.setItem('casdoor-state', state);
const sdk = new Sdk(sdkConfig);

const url = await sdk.getSigninUrl();
Expand All @@ -73,7 +71,7 @@ describe('getSigninUrl', () => {
const sdk = new Sdk(sdkConfig);

const url = await sdk.getSigninUrl();
const state = await AsyncStorage.getItem('casdoor-state'); // 使用await等待异步操作完成
const state = await AsyncStorage.getItem('casdoor-state');

expect(url).toContain(`state=${state}`);
});
Expand Down
12 changes: 12 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1774,6 +1774,11 @@ cross-spawn@^7.0.3:
shebang-command "^2.0.0"
which "^2.0.1"

crypto-js@3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.3.0.tgz#846dd1cce2f68aacfa156c8578f926a609b7976b"
integrity sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q==

crypto-random-string@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5"
Expand Down Expand Up @@ -4758,6 +4763,13 @@ react-is@^17.0.1:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==

react-native-pkce-challenge@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/react-native-pkce-challenge/-/react-native-pkce-challenge-5.2.0.tgz#8696bba05062a463bb4a695366c11c35ad3f1202"
integrity sha512-iuOi0t8NfTzOLFkGECyVHgdUeqawKQYXdW7O4/4MncGHGYnWMCPk4EKvdPdmricIXfPq18uKb5w5RacMo25poA==
dependencies:
crypto-js "3.3.0"

read-cmd-shim@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-2.0.0.tgz#4a50a71d6f0965364938e9038476f7eede3928d9"
Expand Down

0 comments on commit a75a901

Please sign in to comment.