Read the original article:Get an access token after the authorization for the Health Kit
Requirement Description
User wants to get health data, but needs an access token to send a request health endpoint. How can the user get an access token?
Background Knowledge
1) Generate an authorization code.
- The code is obtained by redirecting the user's browser to the address
https://oauth-login.cloud.huawei.com/oauth2/v3/authorize. If an error occurs, please refer to Errors and Troubleshooting.
2) Generate an access token based on the authorization code.
- After obtaining the authorization code in the previous step, it can be used to generate an access token by sending a request using the POST method from the app's server to the Huawei OAuth 2.0 authorization service address
https://oauth-login.cloud.huawei.com/oauth2/v3/tokenwith some input parameters:
3) After the access token expires, use the refresh token to obtain a new access token.
- A refresh token can be used to obtain a new access token by sending a request using the POST method from the app's server to the Huawei OAuth 2.0 authorization service address
https://oauth-login.cloud.huawei.com/oauth2/v3/tokenwith some input parameters.
Implementation Steps
1) Define the client_id, client_secret, auth_url, redirect_url to get access token.
2) Send a token request with the authorization code received from the user during the OAuth authentication process, store the received tokens, and provide helper methods for storing the access token.
To obtain an authorization code, the user is redirected to a URL. After the user grants permission, an authorization code is returned.
3) After receiving the authorization code from the user, an access token is obtained using this code. If the token is already stored, the user is redirected directly to the application without needing to authenticate again.
Code Snippet / Configuration
1) We need to define the client_id, client_secret, auth_url, redirect_url to get access token.
export class APIConstants {
static readonly AUTH_URL: string = 'YOUR_URL'
static readonly CLIENT_ID: string = 'YOUR_CLIENT_ID'
static readonly CLIENT_SECRET: string = 'YOUR_CLIENT_SECRET'
static readonly REDIRECT_URL: string = 'YOUR_REDIRECT_URL'
}
2) This class sends a token request with the authorization code received from the user during the OAuth authentication process, stores the received tokens, and provides helper methods for storing the access token.
To obtain an authorization_code, the user is redirected to a URL. After the user grants permission, an authorization code is returned.
import Preferences from '../common/Preferences';
import { APIConstants } from '../common/Constants';
import { http } from '@kit.NetworkKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { TokenResponse } from '../model/TokenResponse';
import taskpool from '@ohos.taskpool';
import { processRespTask } from '../common/processRespTask';
export class AuthenticationViewModel {
accessToken: string = '';
getAccessTokenFromStorage(): string {
const token = Preferences.instance.getPreference('accessToken');
this.accessToken = token;
return token;
}
saveTokens(accessToken: string, refreshToken: string) {
Preferences.instance.putPreference('accessToken', accessToken);
Preferences.instance.putPreference('refreshToken', refreshToken);
this.accessToken = accessToken;
}
getQueryParameter(url: string, paramName: string): string | null {
const queryStartIndex = url.indexOf('?');
if (queryStartIndex === -1) {
return null;
}
const queryString = url.substring(queryStartIndex + 1);
const params = queryString.split('&');
for (const param of params) {
const parts = param.split('=');
if (parts.length === 2) {
const key = decodeURIComponent(parts[0]);
const value = decodeURIComponent(parts[1]);
if (key === paramName) {
return value;
}
}
}
return null;
}
async postOAuthToken(code: string): Promise<string | null> {
const httpRequest = http.createHttp();
const body =
'grant_type=authorization_code' +
`&code=${encodeURIComponent(code)}` +
`&client_id=${encodeURIComponent(APIConstants.CLIENT_ID)}` +
`&client_secret=${encodeURIComponent(APIConstants.CLIENT_SECRET)}` +
`&redirect_uri=${encodeURIComponent(APIConstants.REDIRECT_URL)}`;
return new Promise((resolve, reject) => {
httpRequest.request(
APIConstants.AUTH_URL,
{
method: http.RequestMethod.POST,
header: {
'Content-Type': 'application/x-www-form-urlencoded',
},
extraData: body,
expectDataType: http.HttpDataType.STRING,
},
async (err: BusinessError, data) => {
let task = new taskpool.Task(processRespTask, [err, data]);
await taskpool.execute(task);
let parsed: TokenResponse | null = null;
if (typeof data.result === 'string') {
try {
parsed = JSON.parse(data.result) as TokenResponse;
} catch (e) {
console.error('JSON parse failed:', e);
resolve(null);
return;
}
} else if (typeof data.result === 'object') {
parsed = data.result as TokenResponse;
}
if (parsed && parsed.access_token && parsed.refresh_token) {
this.saveTokens(parsed.access_token, parsed.refresh_token);
resolve(parsed.access_token);
} else {
console.error('Token parse error or missing fields:', parsed);
resolve(null);
}
}
);
});
}
}
3) After receiving the authorization code from the user, an access token is obtained using this code. If the token is already stored, the user is redirected directly to the application without needing to authenticate again.
import { AuthenticationViewModel } from '../viewmodel/AuthenticationViewModel';
import { APIConstants } from '../common/Constants';
import { webview } from '@kit.ArkWeb';
import { router } from '@kit.ArkUI';
import { ButtonComponent } from '../component/ButtonComponent';
import { BusinessError } from '@kit.BasicServicesKit';
@Entry
@Component
export struct Authentication {
@State shouldShowWebView: boolean = true;
@State accessToken: string = '';
@State activationKey: string = '';
controller: webview.WebviewController = new webview.WebviewController();
private viewModel = new AuthenticationViewModel();
aboutToAppear(): void {
const storedToken = this.viewModel.getAccessTokenFromStorage();
if (storedToken.length > 0) {
this.accessToken = storedToken;
this.shouldShowWebView = false;
}
}
handleOAuthCode(code: string) {
this.activationKey = code;
this.shouldShowWebView = false;
this.viewModel.postOAuthToken(code).then((token) => {
if (token) {
this.accessToken = token;
}
}).catch((e: BusinessError) => {
console.error('Token exchange failed:', e);
});
}
build() {
Column() {
if (this.shouldShowWebView) {
Web({ src: APIConstants.AUTH_URL, controller: this.controller })
.width('100%')
.height('100%')
.onLoadIntercept((event) => {
if (event) {
const url = event.data.getRequestUrl();
console.log('URL:' + url);
const code = this.viewModel.getQueryParameter(url, 'code');
if (code) {
console.info('Code received from redirect: ' + code);
this.handleOAuthCode(code);
}
}
return false;
});
} else {
Column() {
Text($r('app.string.access_token'))
.fontSize(12)
.height('20%')
.width('100%')
.fontWeight(FontWeight.Bold)
.textAlign(TextAlign.Center);
Text(this.accessToken)
.fontSize(12)
.height('30%')
.width('100%')
.fontColor(Color.Red);
ButtonComponent({ text: $r('app.string.continue') })
.margin({ bottom: 5 })
.onClick(() => {
router.pushUrl({ url: 'pages/HomePage' });
});
ButtonComponent({ text: $r('app.string.steps') })
.margin({ bottom: 5 })
.onClick(() => {
router.pushUrl({
url: 'pages/StepsPage',
params: { access_token: this.accessToken }
});
});
}
.height('100%')
.width('100%');
}
}
.height('100%')
.width('100%');
}
}
Test Results
Limitations or Considerations
You need to apply for the Huawei Health application. After approval, you can get data from the Huawei Health.
Related Documents or Links
https://developer.huawei.com/consumer/en/doc/HMSCore-Guides/description-0000001558389985

Top comments (0)