> Portal Navigation: > > - Append `.md` to any URL under `https://dev.wix.com/docs/` to get its markdown version. > - Pages are either content pages (article or reference text) or menu pages (a list of links to child pages). > - To get a menu page, truncate any URL to a parent path and append `.md` (e.g. `https://dev.wix.com/docs/sdk.md`, `https://dev.wix.com/docs/sdk/core-modules.md`). > - Top-level index of all portals: https://dev.wix.com/docs/llms.txt > - Full concatenated docs: https://dev.wix.com/docs/llms-full.txt ## Resource: AppStrategy ## Article: AppOAuthStrategy ## Article Link: https://dev.wix.com/docs/sdk/core-modules/sdk/app-strategy.md ## Article Content: # AppStrategy
__Note:__ This strategy is only intended for [backend extensions](https://dev.wix.com/docs/build-apps/develop-your-app/extensions/backend-extensions/about-backend-extensions.md). For [frontend extensions](https://dev.wix.com/docs/build-apps/develop-your-app/extensions/about-extensions.md#frontend-extensions), use [host modules](https://dev.wix.com/docs/sdk/host-modules/about-host-modules.md) instead.This strategy is used along with a [`Wix Client`](https://dev.wix.com/docs/sdk/core-modules/sdk/wix-client.md) to authenticate API calls made by Wix apps using OAuth tokens. The resulting access token is specific to a particular app instance. For more information, see [About OAuth](https://dev.wix.com/docs/build-apps/develop-your-app/access/authentication/about-oauth.md). Get the access token by using one of the following methods: * Provide the specific app instance ID. For an example, see [Use OAuth](#use-oauth). * Provide the refresh token of a specific app instance obtained during [custom authentication (legacy)](https://dev.wix.com/docs/build-apps/develop-your-app/access/authentication/custom-authentication-legacy.md). This approach is based on the OAuth Authorization Code flow and requires storing a persistent mapping between instance IDs and refresh tokens in a database or similar storage solution. For an example, see [Custom authentication (legacy)](#custom-authentication-legacy). When using this authentication strategy, the requester's identity is that of the corresponding Wix app. The permissions for the app are set in the Dev Center. To learn more about permissions, see [How to Add Permissions](https://dev.wix.com/docs/build-apps/develop-your-app/access/authorization/about-permissions.md). ## AppStrategy() Creates an authentication strategy object that uses OAuth tokens for app authentication. #### Syntax ```js AppStrategy({appId: string, appSecret: string, publicKey?: string, instanceId?: string, refreshToken?: string}): AppStrategy ``` #### Parameters | Name | Type | Description | | :------------------------------- | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `appId` | string | The app ID. You can find this value in the Dev Center in the **OAuth** page. | | `appSecret` | string | The app secret. You can find this value in the Dev Center in the **OAuth** page. | | `publicKey` | string | **Optional.** The app public key in the case of using webhooks. [Find your app's public key](https://dev.wix.com/docs/build-apps/develop-your-app/frameworks/self-hosting/webhooks/handle-events-with-webhooks-for-self-hosting-using-the-java-script-sdk.md). | | **One of:** | | | |
Important: If a `refreshToken` or `instanceId` was passed to `AppStrategy` upon initialization, rather than an `accessToken`, then this method throws an error.#### Syntax ```js getTokenInfo(): Promise
**Caution:** Custom authentication (legacy) is no longer available for new apps. This section is only relevant for existing apps that already use custom authentication.The following code example shows how to implement custom authentication, which follows the OAuth Authorization Code protocol. In this backend code, the user is redirected to the install URL to acquire an authorization code. The user is prompted to approve the required permissions for installation. Then, the access token, refresh token, and instance ID are retrieved and stored for future use. ```js import { createClient, AppStrategy } from '@wix/sdk'; import { products } from '@wix/stores'; const myClient = createClient({ auth: AppStrategy({ appId: 'YOUR_APP_ID', appSecret: 'YOUR_APP_SECRET', publicKey: 'YOUR_APP_PUBLIC_KEY_IF_YOU_USE_WEBHOOKS', }), modules: { products, } }); // Implement a function to redirect the user to the install URL. // Then, the user is sent to the redirect URI with an authorization code. redirectUsingYourServer(myClient.auth.getInstallUrl({ redirectUrl: 'YOUR_REDIRECT_URL' })); // In your redirect URL endpoint, get the access token, refresh token, and instance ID. const { accessToken, refreshToken, instanceId } = await myClient.auth.handleOAuthCallback(request.url); // Store the mapping between the instance ID and the refresh token in persistent storage. await storeRefreshTokenInStorage(instanceId, refreshToken); ``` Then, in the frontend code, the stored refresh token is fetched from storage based on the instance ID and used to create a Wix client with the `AppStrategy` bound to this token. This configuration enables the client to make authenticated API calls. ```js import { createClient, AppStrategy } from '@wix/sdk'; import { products } from '@wix/stores'; // Implement a function to get the instance ID of the relevant app. // The implementation depends on the environment from which you're using the SDK. const instanceId = getInstanceIdFromEnvironment(); // Implement a function to get the refresh token of the relevant app instance. // The implementation will depend on the storage solution. const refreshToken = await getRefreshTokenFromStorage(instanceId); // Get a Wix client bound to the refresh token. // Find the app ID and secret in the OAuth page of the Dev Center. // Find your public key in the Webhooks page of the Dev Center. const myClient = createClient({ auth: AppStrategy({ appId: 'YOUR_APP_ID', appSecret: 'YOUR_APP_SECRET', publicKey: 'YOUR_APP_PUBLIC_KEY_IF_YOU_USE_WEBHOOKS', refreshToken }), modules: { products, } }); // Use the client with the `products` module to query products. const { items } = await myClient.products.queryProducts() .startsWith('name', 'shoes') .limit(4) .find(); ```