createSessionStorage
createSessionStorage
creates a server-side session storage that persists session-id
in a cookie.
tsx
const storageconst storage: SessionStorage
= createSessionStorage(alias) createSessionStorage(strategy: SessionIdStorageStrategy): SessionStorage
import createSessionStorage
(storageOptionslet storageOptions: SessionIdStorageStrategy
);
tsx
const storageconst storage: SessionStorage
= createSessionStorage(alias) createSessionStorage(strategy: SessionIdStorageStrategy): SessionStorage
import createSessionStorage
(storageOptionslet storageOptions: SessionIdStorageStrategy
);
Usage
Creating a SessionStorage
tsx
import { createSessionStorage(alias) const createSessionStorage: CreateSessionStorageFunction
import createSessionStorage
} from 'solid-start';
const storageconst storage: SessionStorage
= createSessionStorage(alias) createSessionStorage(strategy: SessionIdStorageStrategy): SessionStorage
import createSessionStorage
({ cookieThe Cookie used to store the session id, or options used to automatically
create one.
(property) SessionIdStorageStrategy.cookie?: Cookie | (CookieParseOptions & CookieSerializeOptions & CookieSignatureOptions & {
name?: string | undefined;
}) | undefined
: { secureSpecifies the boolean value for the
{@link
https://tools.ietf.org/html/rfc6265#section-5.2.5|`Secure` `Set-Cookie` attribute
}
. When truthy, the
`Secure` attribute is set, otherwise it is not. By default, the `Secure` attribute is not set.
*Note* be careful when setting this to `true`, as compliant clients will
not send the cookie back to the server in the future if the browser does
not have an HTTPS connection.
(property) CookieSerializeOptions.secure?: boolean | undefined
: import.metaThe type of `import.meta`.
If you need to declare that a given property exists on `import.meta`,
this type may be augmented via interface merging.
.env(property) ImportMeta.env: ImportMetaEnv
.PROD(property) ImportMetaEnv.PROD: boolean
, secretsAn array of secrets that may be used to sign/unsign the value of a cookie.
The array makes it easy to rotate secrets. New secrets should be added to
the beginning of the array. `cookie.serialize()` will always use the first
value in the array, but `cookie.parse()` may use any of them so that
cookies that were signed with older secrets still work.
(property) CookieSignatureOptions.secrets?: string[] | undefined
: [import.metaThe type of `import.meta`.
If you need to declare that a given property exists on `import.meta`,
this type may be augmented via interface merging.
.env(property) ImportMeta.env: ImportMetaEnv
.VITE_SESSION_SECRET], sameSiteSpecifies the boolean or string to be the value for the
{@link
https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7|`SameSite` `Set-Cookie` attribute
}
.
- `true` will set the `SameSite` attribute to `Strict` for strict same
site enforcement.
- `false` will not set the `SameSite` attribute.
- `'lax'` will set the `SameSite` attribute to Lax for lax same site
enforcement.
- `'strict'` will set the `SameSite` attribute to Strict for strict same
site enforcement.
- `'none'` will set the SameSite attribute to None for an explicit
cross-site cookie.
More information about the different enforcement levels can be found in
{@link
https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7|the specification
}
.
*note* This is an attribute that has not yet been fully standardized, and may change in the future. This also means many clients may ignore this attribute until they understand it.
(property) CookieSerializeOptions.sameSite?: boolean | "lax" | "strict" | "none" | undefined
: "lax", pathSpecifies the value for the
{@link
https://tools.ietf.org/html/rfc6265#section-5.2.4|`Path` `Set-Cookie` attribute
}
.
By default, the path is considered the "default path".
(property) CookieSerializeOptions.path?: string | undefined
: "/", maxAgeSpecifies the number (in seconds) to be the value for the `Max-Age`
`Set-Cookie` attribute. The given number will be converted to an integer
by rounding down. By default, no maximum age is set.
*Note* the
{@link
https://tools.ietf.org/html/rfc6265#section-5.3|cookie storage model specification
}
states that if both `expires` and `maxAge` are set, then `maxAge` takes precedence, but it is
possible not all clients by obey this, so if both are set, they should
point to the same date and time.
(property) CookieSerializeOptions.maxAge?: number | undefined
: 60 * 60 * 24 * 30, // 30 days httpOnlySpecifies the boolean value for the
{@link
https://tools.ietf.org/html/rfc6265#section-5.2.6|`HttpOnly` `Set-Cookie` attribute
}
.
When truthy, the `HttpOnly` attribute is set, otherwise it is not. By
default, the `HttpOnly` attribute is not set.
*Note* be careful when setting this to true, as compliant clients will
not allow client-side JavaScript to see the cookie in `document.cookie`.
(property) CookieSerializeOptions.httpOnly?: boolean | undefined
: true },
async createDataCreates a new record with the given data and returns the session id.
(property) SessionIdStorageStrategy.createData: (data: SessionData, expires?: Date | undefined) => Promise<string>
(data(parameter) data: SessionData
, expires(parameter) expires: Date | undefined
) { return db.sessions.create({ data(property) data: {
expires: Date | undefined;
}
: { ...data(parameter) data: SessionData
, expires(property) expires: Date | undefined
} }) },
async updateDataUpdates data for the given session id.
(property) SessionIdStorageStrategy.updateData: (id: string, data: SessionData, expires?: Date | undefined) => Promise<void>
(id, data(parameter) data: SessionData
, expires(parameter) expires: Date | undefined
) { return db.sessions.update({ where(property) where: {
id: string;
}
: { id }, data(property) data: {
expires: Date | undefined;
}
: { ...data(parameter) data: SessionData
, expires(property) expires: Date | undefined
} }); },
async deleteDataDeletes data for a given session id from the data store.
(property) SessionIdStorageStrategy.deleteData: (id: string) => Promise<void>
(id) { return db.sessions.delete({ where(property) where: {
id: string;
}
: { id } }); },
async readDataReturns data for a given session id, or `null` if there isn't any.
(property) SessionIdStorageStrategy.readData: (id: string) => Promise<SessionData | null>
(id) { return db.sessions.findUnique({ where(property) where: {
id: string;
}
: { id } }); }
});
tsx
import { createSessionStorage(alias) const createSessionStorage: CreateSessionStorageFunction
import createSessionStorage
} from 'solid-start';
const storageconst storage: SessionStorage
= createSessionStorage(alias) createSessionStorage(strategy: SessionIdStorageStrategy): SessionStorage
import createSessionStorage
({ cookieThe Cookie used to store the session id, or options used to automatically
create one.
(property) SessionIdStorageStrategy.cookie?: Cookie | (CookieParseOptions & CookieSerializeOptions & CookieSignatureOptions & {
name?: string | undefined;
}) | undefined
: { secureSpecifies the boolean value for the
{@link
https://tools.ietf.org/html/rfc6265#section-5.2.5|`Secure` `Set-Cookie` attribute
}
. When truthy, the
`Secure` attribute is set, otherwise it is not. By default, the `Secure` attribute is not set.
*Note* be careful when setting this to `true`, as compliant clients will
not send the cookie back to the server in the future if the browser does
not have an HTTPS connection.
(property) CookieSerializeOptions.secure?: boolean | undefined
: import.metaThe type of `import.meta`.
If you need to declare that a given property exists on `import.meta`,
this type may be augmented via interface merging.
.env(property) ImportMeta.env: ImportMetaEnv
.PROD(property) ImportMetaEnv.PROD: boolean
, secretsAn array of secrets that may be used to sign/unsign the value of a cookie.
The array makes it easy to rotate secrets. New secrets should be added to
the beginning of the array. `cookie.serialize()` will always use the first
value in the array, but `cookie.parse()` may use any of them so that
cookies that were signed with older secrets still work.
(property) CookieSignatureOptions.secrets?: string[] | undefined
: [import.metaThe type of `import.meta`.
If you need to declare that a given property exists on `import.meta`,
this type may be augmented via interface merging.
.env(property) ImportMeta.env: ImportMetaEnv
.VITE_SESSION_SECRET], sameSiteSpecifies the boolean or string to be the value for the
{@link
https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7|`SameSite` `Set-Cookie` attribute
}
.
- `true` will set the `SameSite` attribute to `Strict` for strict same
site enforcement.
- `false` will not set the `SameSite` attribute.
- `'lax'` will set the `SameSite` attribute to Lax for lax same site
enforcement.
- `'strict'` will set the `SameSite` attribute to Strict for strict same
site enforcement.
- `'none'` will set the SameSite attribute to None for an explicit
cross-site cookie.
More information about the different enforcement levels can be found in
{@link
https://tools.ietf.org/html/draft-ietf-httpbis-rfc6265bis-03#section-4.1.2.7|the specification
}
.
*note* This is an attribute that has not yet been fully standardized, and may change in the future. This also means many clients may ignore this attribute until they understand it.
(property) CookieSerializeOptions.sameSite?: boolean | "lax" | "strict" | "none" | undefined
: "lax", pathSpecifies the value for the
{@link
https://tools.ietf.org/html/rfc6265#section-5.2.4|`Path` `Set-Cookie` attribute
}
.
By default, the path is considered the "default path".
(property) CookieSerializeOptions.path?: string | undefined
: "/", maxAgeSpecifies the number (in seconds) to be the value for the `Max-Age`
`Set-Cookie` attribute. The given number will be converted to an integer
by rounding down. By default, no maximum age is set.
*Note* the
{@link
https://tools.ietf.org/html/rfc6265#section-5.3|cookie storage model specification
}
states that if both `expires` and `maxAge` are set, then `maxAge` takes precedence, but it is
possible not all clients by obey this, so if both are set, they should
point to the same date and time.
(property) CookieSerializeOptions.maxAge?: number | undefined
: 60 * 60 * 24 * 30, // 30 days httpOnlySpecifies the boolean value for the
{@link
https://tools.ietf.org/html/rfc6265#section-5.2.6|`HttpOnly` `Set-Cookie` attribute
}
.
When truthy, the `HttpOnly` attribute is set, otherwise it is not. By
default, the `HttpOnly` attribute is not set.
*Note* be careful when setting this to true, as compliant clients will
not allow client-side JavaScript to see the cookie in `document.cookie`.
(property) CookieSerializeOptions.httpOnly?: boolean | undefined
: true },
async createDataCreates a new record with the given data and returns the session id.
(property) SessionIdStorageStrategy.createData: (data: SessionData, expires?: Date | undefined) => Promise<string>
(data(parameter) data: SessionData
, expires(parameter) expires: Date | undefined
) { return db.sessions.create({ data(property) data: {
expires: Date | undefined;
}
: { ...data(parameter) data: SessionData
, expires(property) expires: Date | undefined
} }) },
async updateDataUpdates data for the given session id.
(property) SessionIdStorageStrategy.updateData: (id: string, data: SessionData, expires?: Date | undefined) => Promise<void>
(id, data(parameter) data: SessionData
, expires(parameter) expires: Date | undefined
) { return db.sessions.update({ where(property) where: {
id: string;
}
: { id }, data(property) data: {
expires: Date | undefined;
}
: { ...data(parameter) data: SessionData
, expires(property) expires: Date | undefined
} }); },
async deleteDataDeletes data for a given session id from the data store.
(property) SessionIdStorageStrategy.deleteData: (id: string) => Promise<void>
(id) { return db.sessions.delete({ where(property) where: {
id: string;
}
: { id } }); },
async readDataReturns data for a given session id, or `null` if there isn't any.
(property) SessionIdStorageStrategy.readData: (id: string) => Promise<SessionData | null>
(id) { return db.sessions.findUnique({ where(property) where: {
id: string;
}
: { id } }); }
});
Reading the session data of the current request
tsx
async function getUserIdfunction getUserId(request: Request): Promise<any>
(request(parameter) request: Request
: RequestThis Fetch API interface represents a resource request.
interface Request
) { const session = await storageconst storage: SessionStorage
.getSessionParses a Cookie header from a HTTP request and returns the associated
Session. If there is no session associated with the cookie, this will
return a new Session with no data.
(method) SessionStorage.getSession(cookieHeader?: string | null | undefined, options?: CookieParseOptions | undefined): Promise<Session>
( request(parameter) request: Request
.headersReturns a Headers object consisting of the headers associated with request. Note that headers added in the network layer by the user agent will not be accounted for in this object, e.g., the "Host" header.
(property) Request.headers: Headers
.get(method) Headers.get(name: string): string | null
('Cookie') );
const userId = session.getReturns the value for the given `name` in this session.
(method) Session.get(name: string): any
('userId'); }
tsx
async function getUserIdfunction getUserId(request: Request): Promise<any>
(request(parameter) request: Request
: RequestThis Fetch API interface represents a resource request.
interface Request
) { const session = await storageconst storage: SessionStorage
.getSessionParses a Cookie header from a HTTP request and returns the associated
Session. If there is no session associated with the cookie, this will
return a new Session with no data.
(method) SessionStorage.getSession(cookieHeader?: string | null | undefined, options?: CookieParseOptions | undefined): Promise<Session>
( request(parameter) request: Request
.headersReturns a Headers object consisting of the headers associated with request. Note that headers added in the network layer by the user agent will not be accounted for in this object, e.g., the "Host" header.
(property) Request.headers: Headers
.get(method) Headers.get(name: string): string | null
('Cookie') );
const userId = session.getReturns the value for the given `name` in this session.
(method) Session.get(name: string): any
('userId'); }
Writing the session data for the current request
tsx
async function loginfunction login(request: Request, userId: string): Promise<void>
(request(parameter) request: Request
: RequestThis Fetch API interface represents a resource request.
interface Request
, userId(parameter) userId: string
: string) { const session = await storageconst storage: SessionStorage
.getSessionParses a Cookie header from a HTTP request and returns the associated
Session. If there is no session associated with the cookie, this will
return a new Session with no data.
(method) SessionStorage.getSession(cookieHeader?: string | null | undefined, options?: CookieParseOptions | undefined): Promise<Session>
( request(parameter) request: Request
.headersReturns a Headers object consisting of the headers associated with request. Note that headers added in the network layer by the user agent will not be accounted for in this object, e.g., the "Host" header.
(property) Request.headers: Headers
.get(method) Headers.get(name: string): string | null
('Cookie') );
session.setSets a value in the session for the given `name`.
(method) Session.set(name: string, value: any): void
('userId', userId(parameter) userId: string
); const response = new ResponseThis Fetch API interface represents the response to a request.
var Response: new (body?: BodyInit | null | undefined, init?: ResponseInit | undefined) => Response
('Logged in', { headers(property) ResponseInit.headers?: HeadersInit | undefined
: { 'Set-Cookie': await storageconst storage: SessionStorage
.commitSessionStores all data in the Session and returns the Set-Cookie header to be
used in the HTTP response.
(method) SessionStorage.commitSession(session: Session, options?: CookieSerializeOptions | undefined): Promise<string>
(session) }
});
}
tsx
async function loginfunction login(request: Request, userId: string): Promise<void>
(request(parameter) request: Request
: RequestThis Fetch API interface represents a resource request.
interface Request
, userId(parameter) userId: string
: string) { const session = await storageconst storage: SessionStorage
.getSessionParses a Cookie header from a HTTP request and returns the associated
Session. If there is no session associated with the cookie, this will
return a new Session with no data.
(method) SessionStorage.getSession(cookieHeader?: string | null | undefined, options?: CookieParseOptions | undefined): Promise<Session>
( request(parameter) request: Request
.headersReturns a Headers object consisting of the headers associated with request. Note that headers added in the network layer by the user agent will not be accounted for in this object, e.g., the "Host" header.
(property) Request.headers: Headers
.get(method) Headers.get(name: string): string | null
('Cookie') );
session.setSets a value in the session for the given `name`.
(method) Session.set(name: string, value: any): void
('userId', userId(parameter) userId: string
); const response = new ResponseThis Fetch API interface represents the response to a request.
var Response: new (body?: BodyInit | null | undefined, init?: ResponseInit | undefined) => Response
('Logged in', { headers(property) ResponseInit.headers?: HeadersInit | undefined
: { 'Set-Cookie': await storageconst storage: SessionStorage
.commitSessionStores all data in the Session and returns the Set-Cookie header to be
used in the HTTP response.
(method) SessionStorage.commitSession(session: Session, options?: CookieSerializeOptions | undefined): Promise<string>
(session) }
});
}
Deleting the session data for the current request
tsx
import { redirectA redirect response. Sets the status code and the `Location` header.
Defaults to "302 Found".
(alias) function redirect(url: string, init?: number | ResponseInit): Response
import redirect
} from 'solid-start';
async function logoutfunction logout(request: Request): Promise<Response>
(request(parameter) request: Request
: RequestThis Fetch API interface represents a resource request.
interface Request
) { const session = await storageconst storage: SessionStorage
.getSessionParses a Cookie header from a HTTP request and returns the associated
Session. If there is no session associated with the cookie, this will
return a new Session with no data.
(method) SessionStorage.getSession(cookieHeader?: string | null | undefined, options?: CookieParseOptions | undefined): Promise<Session>
( request(parameter) request: Request
.headersReturns a Headers object consisting of the headers associated with request. Note that headers added in the network layer by the user agent will not be accounted for in this object, e.g., the "Host" header.
(property) Request.headers: Headers
.get(method) Headers.get(name: string): string | null
('Cookie') );
return redirectA redirect response. Sets the status code and the `Location` header.
Defaults to "302 Found".
(alias) redirect(url: string, init?: number | ResponseInit): Response
import redirect
("/login", { headers(property) ResponseInit.headers?: HeadersInit | undefined
: { "Set-Cookie": await storageconst storage: SessionStorage
.destroySessionDeletes all data associated with the Session and returns the Set-Cookie
header to be used in the HTTP response.
(method) SessionStorage.destroySession(session: Session, options?: CookieSerializeOptions | undefined): Promise<string>
(session) }
});
}
tsx
import { redirectA redirect response. Sets the status code and the `Location` header.
Defaults to "302 Found".
(alias) function redirect(url: string, init?: number | ResponseInit): Response
import redirect
} from 'solid-start';
async function logoutfunction logout(request: Request): Promise<Response>
(request(parameter) request: Request
: RequestThis Fetch API interface represents a resource request.
interface Request
) { const session = await storageconst storage: SessionStorage
.getSessionParses a Cookie header from a HTTP request and returns the associated
Session. If there is no session associated with the cookie, this will
return a new Session with no data.
(method) SessionStorage.getSession(cookieHeader?: string | null | undefined, options?: CookieParseOptions | undefined): Promise<Session>
( request(parameter) request: Request
.headersReturns a Headers object consisting of the headers associated with request. Note that headers added in the network layer by the user agent will not be accounted for in this object, e.g., the "Host" header.
(property) Request.headers: Headers
.get(method) Headers.get(name: string): string | null
('Cookie') );
return redirectA redirect response. Sets the status code and the `Location` header.
Defaults to "302 Found".
(alias) redirect(url: string, init?: number | ResponseInit): Response
import redirect
("/login", { headers(property) ResponseInit.headers?: HeadersInit | undefined
: { "Set-Cookie": await storageconst storage: SessionStorage
.destroySessionDeletes all data associated with the Session and returns the Set-Cookie
header to be used in the HTTP response.
(method) SessionStorage.destroySession(session: Session, options?: CookieSerializeOptions | undefined): Promise<string>
(session) }
});
}
Creating a new session
tsx
async function signUpfunction signUp(request: Request, userId: string): Promise<Response>
(request(parameter) request: Request
: RequestThis Fetch API interface represents a resource request.
interface Request
, userId(parameter) userId: string
: string) { const session = await storageconst storage: SessionStorage
.getSessionParses a Cookie header from a HTTP request and returns the associated
Session. If there is no session associated with the cookie, this will
return a new Session with no data.
(method) SessionStorage.getSession(cookieHeader?: string | null | undefined, options?: CookieParseOptions | undefined): Promise<Session>
(); session.setSets a value in the session for the given `name`.
(method) Session.set(name: string, value: any): void
("userId", userId(parameter) userId: string
); return new ResponseThis Fetch API interface represents the response to a request.
var Response: new (body?: BodyInit | null | undefined, init?: ResponseInit | undefined) => Response
('Signed Up', { headers(property) ResponseInit.headers?: HeadersInit | undefined
: { "Set-Cookie": await storageconst storage: SessionStorage
.commitSessionStores all data in the Session and returns the Set-Cookie header to be
used in the HTTP response.
(method) SessionStorage.commitSession(session: Session, options?: CookieSerializeOptions | undefined): Promise<string>
(session) }
});
}
tsx
async function signUpfunction signUp(request: Request, userId: string): Promise<Response>
(request(parameter) request: Request
: RequestThis Fetch API interface represents a resource request.
interface Request
, userId(parameter) userId: string
: string) { const session = await storageconst storage: SessionStorage
.getSessionParses a Cookie header from a HTTP request and returns the associated
Session. If there is no session associated with the cookie, this will
return a new Session with no data.
(method) SessionStorage.getSession(cookieHeader?: string | null | undefined, options?: CookieParseOptions | undefined): Promise<Session>
(); session.setSets a value in the session for the given `name`.
(method) Session.set(name: string, value: any): void
("userId", userId(parameter) userId: string
); return new ResponseThis Fetch API interface represents the response to a request.
var Response: new (body?: BodyInit | null | undefined, init?: ResponseInit | undefined) => Response
('Signed Up', { headers(property) ResponseInit.headers?: HeadersInit | undefined
: { "Set-Cookie": await storageconst storage: SessionStorage
.commitSessionStores all data in the Session and returns the Set-Cookie header to be
used in the HTTP response.
(method) SessionStorage.commitSession(session: Session, options?: CookieSerializeOptions | undefined): Promise<string>
(session) }
});
}