mirror of
https://github.com/LukeHagar/better-auth.git
synced 2025-12-10 12:27:44 +00:00
Revert "fix(bearer): certain sign-in endpoints won't give bearer token (#4123)"
This reverts commit 4c377f640d.
This commit is contained in:
@@ -22,15 +22,6 @@ export const auth = betterAuth({
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
And in your auth client as well:
|
|
||||||
|
|
||||||
```ts title="auth-client.ts"
|
|
||||||
import { bearerClient } from "better-auth/client/plugins";
|
|
||||||
export const authClient = createAuthClient({
|
|
||||||
plugins: [bearerClient()]
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
## How to Use Bearer Tokens
|
## How to Use Bearer Tokens
|
||||||
|
|
||||||
### 1. Obtain the Bearer Token
|
### 1. Obtain the Bearer Token
|
||||||
@@ -66,6 +57,7 @@ export const authClient = createAuthClient({
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
You may want to clear the token based on the response status code or other conditions:
|
You may want to clear the token based on the response status code or other conditions:
|
||||||
|
|
||||||
### 2. Configure the Auth Client
|
### 2. Configure the Auth Client
|
||||||
@@ -145,6 +137,3 @@ export async function handler(req, res) {
|
|||||||
## Options
|
## Options
|
||||||
|
|
||||||
**requireSignature** (boolean): Require the token to be signed. Default: `false`.
|
**requireSignature** (boolean): Require the token to be signed. Default: `false`.
|
||||||
|
|
||||||
**cookieName** (string): Custom cookie name for the temporary bearer token confirmation cookie. Default: `"bearer-token-confirmation"`.
|
|
||||||
(For more information, [read here](https://github.com/better-auth/better-auth/pull/4123))
|
|
||||||
@@ -1 +1 @@
|
|||||||
IDLE
|
RUNNING
|
||||||
@@ -19,6 +19,5 @@ export * from "../../plugins/oidc-provider/client";
|
|||||||
export * from "../../plugins/api-key/client";
|
export * from "../../plugins/api-key/client";
|
||||||
export * from "../../plugins/one-time-token/client";
|
export * from "../../plugins/one-time-token/client";
|
||||||
export * from "../../plugins/siwe/client";
|
export * from "../../plugins/siwe/client";
|
||||||
export * from "../../plugins/bearer/client";
|
|
||||||
export * from "../../plugins/device-authorization/client";
|
export * from "../../plugins/device-authorization/client";
|
||||||
export type * from "@simplewebauthn/server";
|
export type * from "@simplewebauthn/server";
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
import type { BetterAuthClientPlugin } from "../../types";
|
|
||||||
|
|
||||||
export const bearerClient = () => {
|
|
||||||
return {
|
|
||||||
id: "bearer",
|
|
||||||
getActions($fetch, $store, options) {
|
|
||||||
if (typeof document === "undefined") return {};
|
|
||||||
const cookie = document.cookie;
|
|
||||||
if (cookie.includes("bearer-token=true")) {
|
|
||||||
// This will hit the endpoint which would grab the bearer token cookie if it exists, then delete said cookie
|
|
||||||
// It will then return the bearer token in the response which should be caught on the authClient's `onSuccess` hook
|
|
||||||
$fetch("/get-bearer-token");
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
},
|
|
||||||
} satisfies BetterAuthClientPlugin;
|
|
||||||
};
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { serializeSignedCookie } from "better-call";
|
import { serializeSignedCookie } from "better-call";
|
||||||
import type { BetterAuthPlugin } from "../../types/plugins";
|
import type { BetterAuthPlugin } from "../../types/plugins";
|
||||||
import { parseSetCookieHeader } from "../../cookies";
|
import { parseSetCookieHeader } from "../../cookies";
|
||||||
import { createAuthEndpoint, createAuthMiddleware } from "../../api";
|
import { createAuthMiddleware } from "../../api";
|
||||||
import { createHMAC } from "@better-auth/utils/hmac";
|
import { createHMAC } from "@better-auth/utils/hmac";
|
||||||
|
|
||||||
interface BearerOptions {
|
interface BearerOptions {
|
||||||
@@ -13,76 +13,14 @@ interface BearerOptions {
|
|||||||
* @default false
|
* @default false
|
||||||
*/
|
*/
|
||||||
requireSignature?: boolean;
|
requireSignature?: boolean;
|
||||||
/**
|
|
||||||
* Custom cookie name for the temporary bearer token confirmation cookie.
|
|
||||||
*
|
|
||||||
* @default "bearer-token-confirmation"
|
|
||||||
*/
|
|
||||||
cookieName?: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts bearer token to session cookie
|
* Converts bearer token to session cookie
|
||||||
*/
|
*/
|
||||||
export const bearer = (options?: BearerOptions) => {
|
export const bearer = (options?: BearerOptions) => {
|
||||||
const bearerConfirmationCookieName =
|
|
||||||
options?.cookieName || "bearer-token-confirmation";
|
|
||||||
return {
|
return {
|
||||||
id: "bearer",
|
id: "bearer",
|
||||||
endpoints: {
|
|
||||||
getBearerToken: createAuthEndpoint(
|
|
||||||
"/get-bearer-token",
|
|
||||||
{
|
|
||||||
method: "GET",
|
|
||||||
metadata: {
|
|
||||||
client: false,
|
|
||||||
},
|
|
||||||
requireHeaders: true,
|
|
||||||
},
|
|
||||||
async (ctx) => {
|
|
||||||
const cookieString = ctx.headers.get("cookie");
|
|
||||||
if (!cookieString) {
|
|
||||||
return ctx.json({
|
|
||||||
success: false,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
const cookies = cookieString
|
|
||||||
.split(";")
|
|
||||||
.map((cookie) => cookie.trim());
|
|
||||||
const foundBearerToken = cookies.find((cookie) =>
|
|
||||||
cookie.startsWith(`${bearerConfirmationCookieName}=`),
|
|
||||||
);
|
|
||||||
const foundSessionToken = cookies.find((cookie) =>
|
|
||||||
cookie.startsWith(ctx.context.authCookies.sessionToken.name),
|
|
||||||
);
|
|
||||||
if (foundBearerToken && foundSessionToken) {
|
|
||||||
const setCookie = foundSessionToken.split("=")[1];
|
|
||||||
const parsedCookies = parseSetCookieHeader(setCookie);
|
|
||||||
const cookieName = ctx.context.authCookies.sessionToken.name;
|
|
||||||
const sessionCookie = parsedCookies.get(cookieName);
|
|
||||||
if (
|
|
||||||
!sessionCookie ||
|
|
||||||
!sessionCookie.value ||
|
|
||||||
sessionCookie["max-age"] === 0
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const token = sessionCookie.value;
|
|
||||||
ctx.setHeader("set-auth-token", token);
|
|
||||||
ctx.setHeader(
|
|
||||||
"set-cookie",
|
|
||||||
`${bearerConfirmationCookieName}=; Path=/; HttpOnly; SameSite=Strict; Max-Age=0; Expires=Thu, 01 Jan 1970 00:00:00 GMT`,
|
|
||||||
);
|
|
||||||
return ctx.json({
|
|
||||||
success: true,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return ctx.json({
|
|
||||||
success: false,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
),
|
|
||||||
},
|
|
||||||
hooks: {
|
hooks: {
|
||||||
before: [
|
before: [
|
||||||
{
|
{
|
||||||
@@ -176,19 +114,6 @@ export const bearer = (options?: BearerOptions) => {
|
|||||||
.filter(Boolean),
|
.filter(Boolean),
|
||||||
);
|
);
|
||||||
headersSet.add("set-auth-token");
|
headersSet.add("set-auth-token");
|
||||||
const location =
|
|
||||||
ctx.context.responseHeaders?.get("location") ||
|
|
||||||
ctx.context.responseHeaders?.get("Location");
|
|
||||||
// If location exists, it likely means the authClient isn't able to pick up the bearer token.
|
|
||||||
// We will store a "bearer-token-confirmation" cookie so that when the authClient loads it can hit the
|
|
||||||
// `/get-bearer-token` endpoint and check for it, then delete it and return the bearer token.
|
|
||||||
if (location) {
|
|
||||||
// set a temporary cookie that will be used to get the bearer token
|
|
||||||
ctx.setHeader(
|
|
||||||
"set-cookie",
|
|
||||||
`${bearerConfirmationCookieName}=true; Path=/; SameSite=Strict; Secure`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
ctx.setHeader("set-auth-token", token);
|
ctx.setHeader("set-auth-token", token);
|
||||||
ctx.setHeader(
|
ctx.setHeader(
|
||||||
"Access-Control-Expose-Headers",
|
"Access-Control-Expose-Headers",
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import { MongoClient } from "mongodb";
|
|||||||
import { mongodbAdapter } from "../adapters/mongodb-adapter";
|
import { mongodbAdapter } from "../adapters/mongodb-adapter";
|
||||||
import { createPool } from "mysql2/promise";
|
import { createPool } from "mysql2/promise";
|
||||||
import { bearer } from "../plugins";
|
import { bearer } from "../plugins";
|
||||||
import { bearerClient } from "../client/plugins";
|
|
||||||
|
|
||||||
const cleanupSet = new Set<Function>();
|
const cleanupSet = new Set<Function>();
|
||||||
|
|
||||||
@@ -248,10 +247,6 @@ export async function getTestInstance<
|
|||||||
|
|
||||||
const client = createAuthClient({
|
const client = createAuthClient({
|
||||||
...(config?.clientOptions as C extends undefined ? {} : C),
|
...(config?.clientOptions as C extends undefined ? {} : C),
|
||||||
plugins: [
|
|
||||||
bearerClient(),
|
|
||||||
...((config?.clientOptions?.plugins as C["plugins"]) || []),
|
|
||||||
],
|
|
||||||
baseURL: getBaseURL(
|
baseURL: getBaseURL(
|
||||||
options?.baseURL || "http://localhost:" + (config?.port || 3000),
|
options?.baseURL || "http://localhost:" + (config?.port || 3000),
|
||||||
options?.basePath || "/api/auth",
|
options?.basePath || "/api/auth",
|
||||||
|
|||||||
Reference in New Issue
Block a user