Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
233 changes: 233 additions & 0 deletions docs/src/content/docs/oauth/tiktok.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
---
title: TikTok Authorization Provider
description: Add GitHub authorization provider to Aura Auth to authentication and authorize
---

## TikTok

Set up the `TikTok` authorization provider in your Aura Auth instance.

---

## What you'll build

Through this quick start guide you are going to learn and understand the basics and how to set up the `TikTok` provider for Aura Auth.

- [TikTok OAuth App](#tiktok-oauth-app)
- [Installation](#installation)
- [Environment setup](#environment-setup)
- [Configure the Auth Instance](#configure-the-auth-instance)
- [Customizing the OAuth Provider](#customizing-the-oauth-provider)
- [Sign In to TikTok (Client & Server)](#sign-in-to-tiktok-client--server)
- [Resources](#resources)

---

<Steps>

<Step>

## TikTok OAuth App

### Register the Application

The first step is to create and register an OAuth App on the TikTok developer console to obtain access to the user's resources.

1. Navigate to your TikTok Developer Portal and go to **Developer Portal > Manage apps**.
2. Click **Connect an app**.
3. Select **Individual** or **Organization** ownership and click **Confirm**.
4. Fill in the "App name" and "App type".
5. Fill the **Basic information** section with the required details.
- App icon: 1024 x 1024 px
- Category: Select the most relevant category for your app.
- Description: Description of your app's functionality and purpose.
- Terms of Service URL: Link to your app's terms of service.
- Privacy Policy URL: Link to your app's privacy policy.
- Platforms: Select the platforms your app will support (e.g., Web, Desktop, iOS, Android).
6. Fill the **App review** section required to pass the TikTok review process.
- Short description: A concise summary of your app's functionality (max 1000 characters).
7. Add scopes required for your app to function properly. For example, if you need to access user profile information, you would add the `user.info.basic` scope.
8. Read teh complete [App Review Guidelines](https://developers.tiktok.com/doc/app-review-guidelines) to ensure your app meets all requirements before submission.
9. Click **Submit for review**.
10. Ensure you copy the **Client ID** and click **Generate a new client secret**.

</Step>

<Step>

## Installation

Install the package using a package manager like `npm`, `pnpm`, or `yarn`:

```npm
npm install @aura-stack/auth
```

</Step>

<Step>

## Environment setup

Now, you must configure the environment variables required by Aura Auth, including the GitHub credentials and the encryption secrets.

```bash title=".env" lineNumbers
# Aura Secrets
AURA_AUTH_SECRET="your-32-byte-secret"
AURA_AUTH_SALT="your-32-byte-salt"

# TikTok Credentials
AURA_AUTH_TIKTOKE_CLIENT_ID="your_tiktok_client_id"
AURA_AUTH_TIKTOKE_CLIENT_SECRET="your_tiktok_client_secret"
```

<Callout type="warn">
**CRITICAL SECURITY WARNING:** The `AURA_AUTH_SECRET` and `AURA_AUTH_SALT` variables are used to encrypt and sign user sessions.
These MUST be securely generated, highly randomized strings consisting of at least 32 bytes to ensure adequate entropy. Never
hardcode these values in your repository. Use a secure generator (like `openssl rand -base64 32`) to create them, and store them
exclusively in your secure environment variables manager.
</Callout>

</Step>

<Step>

## Configure the Auth Instance

Configure the `createAuth` instance inside an `auth.ts` file located at the root of your project. Ensure you explicitly export the `handlers`, `api`, and `jose` objects.

```ts title="auth.ts" lineNumbers
import { createAuth } from "@aura-stack/auth"

export const auth = createAuth({
oauth: ["tiktok"],
})

// Extract the required utilities
export const { handlers, api, jose } = auth
```

<Callout type="info">
The `handlers` object contains mapping utilities for standard HTTP methods (`GET`, `POST`, `PATCH`) as well as a unified `ALL`
handler. This allows you to easily mount the authentication routes across any framework (Next.js, Elysia, Express, etc.).
</Callout>

</Step>

<Step>

## Customizing the OAuth Provider

If you need to define custom scopes, change the response type, or map profile data differently, you can use the provider's factory function instead of a simple string identifier.

```ts title="auth.ts" lineNumbers
import { createAuth } from "@aura-stack/auth"
import { tiktok } from "@aura-stack/auth/oauth/tiktok"

export const auth = createAuth({
oauth: [
tiktok({
authorize: {
params: {
// Override default scopes
scope: "user.info.stats",
},
},
}),
],
})

export const { handlers, api, jose } = auth
```

</Step>

<Step>

## Sign In to TikTok (Client & Server)

There are multiple ways to trigger the sign-in flow depending on your ecosystem.

### Sign-in Path (Direct Navigation)

The common route to trigger the auth flow natively without needing a client library is simply navigating the browser to:
`http://localhost:3000/auth/signIn/tiktok`

---

### Client-Side (React, Vue, etc.)

You can utilize the `createAuthClient` utility to programmatically trigger sign-ins. You can also define a `redirectTo` destination.

<Callout type="warn">
**Constraint Rule**: The `baseURL` passed into `createAuthClient` MUST exactly match the root domain and path where the HTTP
`handlers` expose their endpoints on the server.
</Callout>

```ts title="components/Login.tsx" lineNumbers
import { createAuthClient } from "@aura-stack/auth/client"

export const authClient = createAuthClient({
baseURL: "http://localhost:3000/auth",
})

const triggerSignIn = async () => {
await authClient.signIn("tiktok", {
redirectTo: "/dashboard",
})
}
```

---

### Server-Side (Next.js Actions, Remix Loaders, etc.)

For environments supporting server-side actions, use the programmatic `api.signIn` method securely.

```ts title="actions.ts" lineNumbers
import { api } from "./auth"

export const serverSignIn = async () => {
const response = await api.signIn("tiktok", {
redirectTo: "http://localhost:3000/dashboard",
})

// Example returning redirect location
return response.headers.get("Location")
}
```

---

### Session Retrieval

After a user successfully signs in, you can retrieve their session data securely.

**Client-Side:**

```ts
const session = await authClient.getSession()
console.log(session?.user) // The authenticated TikTok user profile
```

**Server-Side:**

```ts
// Note: You must pass the native Web Request object or Headers!
const session = await api.getSession(request)
console.log(session?.user) // Safely retrieved backend session
```

</Step>

</Steps>

---

## Resources

- [RFC - The OAuth 2.0 Authorization Framework](https://datatracker.ietf.org/doc/html/rfc6749)
- [TikTok - Manage Apps](https://developers.tiktok.com/apps)
- [TikTok - Scopes](https://developers.tiktok.com/doc/tiktok-api-scopes)
- [TikTok - User Object](https://developers.tiktok.com/doc/tiktok-api-v1-user-info)
- [TikTok - App Review Guidelines](https://developers.tiktok.com/doc/app-review-guidelines)
7 changes: 5 additions & 2 deletions packages/core/src/oauth/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ import { notion } from "./notion.ts"
import { dropbox } from "./dropbox.ts"
import { atlassian } from "./atlassian.ts"
import { clickUp } from "./click-up.ts"
import { dribble } from "./dribble.ts"
import { dribbble } from "./dribble.ts"
import { tiktok } from "./tiktok.ts"
import { formatZodError } from "@/shared/utils.ts"
import { AuthInternalError } from "@/shared/errors.ts"
import { OAuthEnvSchema, OAuthProviderCredentialsSchema } from "@/schemas.ts"
Expand All @@ -41,6 +42,7 @@ export * from "./dropbox.ts"
export * from "./atlassian.ts"
export * from "./click-up.ts"
export * from "./dribble.ts"
export * from "./tiktok.ts"

export const builtInOAuthProviders = {
github,
Expand All @@ -58,7 +60,8 @@ export const builtInOAuthProviders = {
dropbox,
atlassian,
clickUp,
dribble,
dribbble,
tiktok,
} as const

/**
Expand Down
55 changes: 55 additions & 0 deletions packages/core/src/oauth/tiktok.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import type { OAuthProviderConfig, OAuthProviderCredentials, User } from "@/@types/index.js"

/**
* @see [TikTok - User Object](https://developers.tiktok.com/doc/tiktok-api-v1-user-info)
*/
export interface TikTokProfile {
open_id: string
union_id: string
avatar_url: string
avatar_url_100: string
avatar_large_url: string
display_name: string
description: string
bio_description: string
profile_deep_link: string
is_verified: boolean
username: string
follower_count: number
following_count: number
likes_count: number
video_count: number
}

/**
* @see [TikTok - Manage Apps](https://developers.tiktok.com/apps)
* @see [TikTok - Scopes](https://developers.tiktok.com/doc/tiktok-api-scopes)
* @see [TikTok - User Object](https://developers.tiktok.com/doc/tiktok-api-v1-user-info)
* @see [TikTok - App Review Guidelines](https://developers.tiktok.com/doc/app-review-guidelines)
* @todo: add `client_key` search parameter in `authorize` endpoint.
*/
export const tiktok = <DefaultUser extends User = User>(
options?: Partial<OAuthProviderConfig<TikTokProfile, DefaultUser>>
): OAuthProviderCredentials<TikTokProfile, DefaultUser> => {
return {
id: "tiktok",
name: "TikTok",
authorize: {
url: "https://www.tiktok.com/v2/auth/authorize",
params: {
scope: "user.info.basic",
response_type: "code",
},
},
accessToken: "https://open.tiktokapis.com/v2/oauth/token",
userInfo: "https://open.tiktokapis.com/v2/user/info",
profile: (profile) =>
({
sub: profile.open_id,
name: profile.display_name,
image: profile.avatar_url_100,
email: "",
}) as DefaultUser,
...options,
}
}
Loading