Skip to content

Commit dcaaf1a

Browse files
wangsijiefalcowinklerbalazsorban44
authored
feat(provider): add Logto provider (#12534)
* feat(provider): add Logto provider * simplify provider, update docs * update getting-started * remove logto from .env.local example * update docs pages manifest * Update logto.ts --------- Co-authored-by: Falco Winkler <8613031+falcowinkler@users.noreply.github.com> Co-authored-by: Balázs Orbán <info@balazsorban.com>
1 parent 857fe15 commit dcaaf1a

File tree

5 files changed

+227
-0
lines changed

5 files changed

+227
-0
lines changed

.github/ISSUE_TEMPLATE/2_bug_provider.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ body:
6363
- "Kinde"
6464
- "Line"
6565
- "LinkedIn"
66+
- "Logto"
6667
- "Loops"
6768
- "Mailchimp"
6869
- "Mail.ru"

docs/pages/data/manifest.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
"kinde": "Kinde",
8585
"line": "LINE",
8686
"linkedin": "LinkedIn",
87+
"logto": "Logto",
8788
"mailchimp": "Mailchimp",
8889
"mailru": "Mail.ru",
8990
"mastodon": "Mastodon",
@@ -141,6 +142,7 @@
141142
"identity-server4",
142143
"keycloak",
143144
"kinde",
145+
"logto",
144146
"mastodon",
145147
"mattermost",
146148
"nextcloud",
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { Callout } from "nextra/components"
2+
import { Code } from "@/components/Code"
3+
4+
<img align="right" src="/img/providers/logto.svg" width="64" height="64" />
5+
6+
# Logto Provider
7+
8+
## Resources
9+
10+
- [Logto Auth.js quickstart](https://docs.logto.io/quick-starts/next-auth)
11+
- [Integrate Logto in your application](https://docs.logto.io/integrate-logto/integrate-logto-into-your-application)
12+
13+
## Setup
14+
15+
### Callback URL
16+
17+
<Code>
18+
<Code.Next>
19+
20+
```bash
21+
https://example.com/api/auth/callback/logto
22+
```
23+
24+
</Code.Next>
25+
<Code.Svelte>
26+
27+
```bash
28+
https://example.com/auth/callback/logto
29+
```
30+
31+
</Code.Svelte>
32+
</Code>
33+
34+
### Environment Variables
35+
36+
```
37+
AUTH_LOGTO_ID
38+
AUTH_LOGTO_SECRET
39+
AUTH_LOGTO_ISSUER
40+
```
41+
42+
### Configuration
43+
44+
<Code>
45+
<Code.Next>
46+
47+
```ts filename="/auth.ts"
48+
import NextAuth from "next-auth"
49+
import Logto from "next-auth/providers/logto"
50+
51+
export const { handlers, auth, signIn, signOut } = NextAuth({
52+
providers: [Logto],
53+
})
54+
```
55+
56+
</Code.Next>
57+
<Code.Svelte>
58+
59+
```ts filename="/src/auth.ts"
60+
import { SvelteKitAuth } from "@auth/sveltekit"
61+
import Logto from "@auth/sveltekit/providers/logto"
62+
63+
export const { handle, signIn, signOut } = SvelteKitAuth({
64+
providers: [Logto],
65+
})
66+
```
67+
68+
</Code.Svelte>
69+
<Code.Express>
70+
71+
```ts filename="/src/app.ts"
72+
import { ExpressAuth } from "@auth/express"
73+
import Logto from "@auth/express/providers/logto"
74+
75+
app.use("/auth/*", ExpressAuth({ providers: [Logto] }))
76+
```
77+
78+
</Code.Express>
79+
</Code>

docs/public/img/providers/logto.svg

Lines changed: 23 additions & 0 deletions
Loading

packages/core/src/providers/logto.ts

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/**
2+
* <div style={{display: "flex", justifyContent: "space-between", alignItems: "center"}}>
3+
* <span style={{fontSize: "1.35rem" }}>
4+
* Built-in sign in with <b>Logto</b> integration.
5+
* </span>
6+
* <a href="https://logto.io" style={{backgroundColor: "black", padding: "12px", borderRadius: "100%" }}>
7+
* <img style={{display: "block"}} src="https://authjs.dev/img/providers/logto.svg" width="24"/>
8+
* </a>
9+
* </div>
10+
*
11+
* @module providers/logto
12+
*/
13+
14+
import type { OIDCConfig, OIDCUserConfig } from "./index.js"
15+
16+
/** The returned user profile from Logto when using the profile callback. [Reference](https://docs.logto.io/quick-starts/next-auth#scopes-and-claims). */
17+
export interface LogtoProfile {
18+
/** The user's unique ID */
19+
sub: string
20+
/** The user's name */
21+
name: string
22+
/** The user's username */
23+
username: string
24+
/** The user's picture */
25+
picture: string
26+
/** The user's email */
27+
email: string
28+
/** A boolean indicating if the user's email is verified */
29+
email_verified: boolean
30+
/** The user's phone number */
31+
phone_number: string
32+
/** A boolean indicating if the user's phone number is verified */
33+
phone_number_verified: boolean
34+
/** The user's address */
35+
address: string
36+
/** Custom fields */
37+
custom_data: object
38+
/** The linked identities of the user */
39+
identities: object
40+
/** The linked SSO identities of the user */
41+
sso_identities: object[]
42+
/** The organization IDs the user belongs to */
43+
organizations: string[]
44+
/** The organization data the user belongs to */
45+
organization_data: object[]
46+
/** The organization roles the user belongs to with the format of <organization_id>:<role_name> */
47+
organization_roles: string[]
48+
/** The user's custom attributes */
49+
[claim: string]: unknown
50+
}
51+
52+
/**
53+
*
54+
* ### Setup
55+
*
56+
* #### Callback URL
57+
* ```
58+
* https://example.com/api/auth/callback/logto
59+
* ```
60+
*
61+
* #### Configuration
62+
* ```ts
63+
* import { Auth } from "@auth/core"
64+
* import Logto from "@auth/core/providers/logto"
65+
*
66+
* const request = new Request(origin)
67+
* const response = await Auth(request, {
68+
* providers: [
69+
* Logto({
70+
* clientId: LOGTO_ID,
71+
* clientSecret: LOGTO_SECRET,
72+
* issuer: LOGTO_ISSUER
73+
* }),
74+
* ],
75+
* })
76+
* ```
77+
*
78+
*
79+
* ### Resources
80+
*
81+
* - [Logto Auth.js quickstart](https://docs.logto.io/quick-starts/next-auth)
82+
* - [Integrate Logto in your application](https://docs.logto.io/integrate-logto/integrate-logto-into-your-application)
83+
*
84+
* ### Notes
85+
*
86+
* The Logto provider comes with a [default configuration](https://github.com/nextauthjs/next-auth/blob/main/packages/core/src/providers/logto.ts). To override the defaults for your use case, check out [customizing a built-in OAuth provider](https://authjs.dev/guides/configuring-oauth-providers).
87+
*
88+
* :::info
89+
* By default, Auth.js assumes that the Logto provider is based on the [OIDC](https://openid.net/specs/openid-connect-core-1_0.html) spec
90+
* :::
91+
*
92+
* ## Help
93+
*
94+
* If you think you found a bug in the default configuration, you can [open an issue](https://authjs.dev/new/provider-issue).
95+
*
96+
* Auth.js strictly adheres to the specification and it cannot take responsibility for any deviation from
97+
* the spec by the provider. You can open an issue, but if the problem is non-compliance with the spec,
98+
* we might not pursue a resolution. You can ask for more help in [Discussions](https://authjs.dev/new/github-discussions).
99+
*/
100+
export default function Logto(
101+
options: OIDCUserConfig<LogtoProfile>
102+
): OIDCConfig<LogtoProfile> {
103+
return {
104+
id: "logto",
105+
name: "Logto",
106+
type: "oidc",
107+
authorization: {
108+
params: {
109+
scope: "offline_access openid email profile",
110+
},
111+
},
112+
profile(profile) {
113+
return {
114+
id: profile.sub,
115+
name: profile.name ?? profile.username,
116+
email: profile.email,
117+
image: profile.picture,
118+
}
119+
},
120+
options,
121+
}
122+
}

0 commit comments

Comments
 (0)