Next.js的輕巧基於承諾的會話中間件還可以在micro或node.js http服務器中工作,Express等。
還要查看諸如Next-Ironssionsssions之類的替代方案。看看NextJS-MongoDB-App以查看使用此模塊。
// NPM
npm install next-session
// Yarn
yarn add next-session從v1.x升級到v2.x?請在此處閱讀發行說明!
從v2.x升級到v3.x?請在此處閱讀發行說明!
從v3.x升級到v4.x?請在此處閱讀發行說明!
警告默認的會話商店(如果options?.store是undefined ), MemoryStore ,在生產或無服務器環境中不起作用。您必須使用會話商店。
// ./lib/get-session.js
import nextSession from "next-session" ;
export const getSession = nextSession ( options ) ; import { getSession } from "./lib/get-session.js" ;
export default function handler ( req , res ) {
const session = await getSession ( req , res ) ;
session . views = session . views ? session . views + 1 : 1 ;
// Also available under req.session:
// req.session.views = req.session.views ? req.session.views + 1 : 1;
res . send (
`In this session, you have visited this website ${ session . views } time(s).`
) ;
}在API路線中使用的使用可能會導致API resolved without sending a response 。這可以通過添加來解決:
import nextSession from "next-session" ;
const getSession = nextSession ( ) ;
export default function handler ( req , res ) {
const session = await getSession ( req , res ) ;
/* ... */
}
export const config = {
api : {
externalResolver : true ,
} ,
} ; ...或設置options.autoCommit to false ,do await session.commit() 。
import nextSession from "next-session" ;
const getSession = nextSession ( { autoCommit : false } ) ;
export default function handler ( req , res ) {
const session = await getSession ( req , res ) ;
/* ... */
await session . commit ( ) ;
} import { getSession } from "./lib/get-session.js" ;
export default function Page ( { views } ) {
return (
< div > In this session, you have visited this website { views } time(s). </ div >
) ;
}
export async function getServerSideProps ( { req , res } ) {
const session = await getSession ( req , res ) ;
session . views = session . views ? session . views + 1 : 1 ;
// Also available under req.session:
// req.session.views = req.session.views ? req.session.views + 1 : 1;
return {
props : {
views : session . views ,
} ,
} ;
}Express,接下來的連接
const express = require ( "express" ) ;
const app = express ( ) ;
app . use ( async ( req , res , next ) => {
await getSession ( req , res ) ; // session is set to req.session
next ( ) ;
} ) ;
app . get ( "/" , ( req , res ) => {
req . session . views = req . session . views ? req . session . views + 1 : 1 ;
res . send (
`In this session, you have visited this website ${ req . session . views } time(s).`
) ;
} ) ;Micro,Vercel無服務器功能
module . exports = ( req , res ) => {
const session = await getSession ( req , res ) ;
res . end (
`In this session, you have visited this website ${ session . views } time(s).`
) ;
} ;Node.js HTTP服務器
const http = require ( "http" ) ;
const server = http . createServer ( async ( req , res ) => {
const session = await getSession ( req , res ) ;
res . end ( `In this session, you have visited this website ${ session . views } time(s).` ;
} ) ;
server . listen ( 8080 ) ; next-session接受以下屬性。
| 選項 | 描述 | 預設 |
|---|---|---|
| 姓名 | 從請求中讀取並將其設置為響應的cookie的名稱。 | sid |
| 店鋪 | 會話存儲實例要使用。需要在生產中工作! | MemoryStore |
| GenID | 為新會話ID生成字符串的功能。 | nanoid |
| 編碼 | 在設置cookie之前轉換會話ID。它採用原始的會話ID並返回解碼/解密的會話ID。 | 不明確的 |
| 解碼 | 從cookie中轉換會話ID。它應該返回編碼/加密的會話ID | 不明確的 |
| 觸摸 | 自上次訪問以來,只有一段時間(以秒為單位)觸摸。默認情況下禁用或設置為-1 。請參閱TouchAfter。 | -1 (禁用) |
| 自動參數 | 自動提交會話。如果您想手動session.commit()禁用此功能 | true |
| cookie.secure | 指定安全Set-Cookie屬性的布爾值。 | false |
| cookie.httponly | 指定httponly Set-Cookie屬性的布爾值。 | true |
| cookie.Path | 指定路徑Set-Cookie屬性的值。 | / |
| cookie.domain | 指定域Set-Cookie屬性的值。 | 不設置 |
| cookie.samesite | 指定Samesite Set-Cookie屬性的值。 | 不設置 |
| cookie.maxage | (以秒為單位)指定Max-Age Set-Cookie屬性的值。 | UNSET(瀏覽器會話) |
觸摸是指在瀏覽器中(通過修改set-cookie標頭中的Expires屬性)和訪問時的會話存儲(使用其各自的方法)中的會話壽命的擴展。這可以防止一段時間後的會話過期。
在autoCommit模式(默認情況下是啟用),為了優化,如果未修改,則只會觸摸,而不會保存。如果會話仍然是最新的,則可以使touchAfter的值可以跳過觸摸,從而減少數據庫負載。
您可以提供一個自定義的函數,該功能在每個請求中編碼/解碼或加密/解密cookie。
// `express-session` signing strategy
const signature = require ( "cookie-signature" ) ;
const secret = "keyboard cat" ;
session ( {
decode : ( raw ) => signature . unsign ( raw . slice ( 2 ) , secret ) ,
encode : ( sid ) => ( sid ? "s:" + signature . sign ( sid , secret ) : null ) ,
} ) ; 這使您可以設置或獲得與當前會話相關聯的特定值。
// Set a value
if ( loggedIn ) session . user = "John Doe" ;
// Get a value
const currentUser = session . user ; // "John Doe"通過Maxage手動擴展會話到期。注意:如果autoCommit = false ,則必須調用Session.Commit()。
session . touch ( ) ;如果設置具有非負值的touchAfter ,則將自動調用。
銷毀當前會話並將其從會話存儲中刪除。
if ( loggedOut ) await session . destroy ( ) ;保存會話並設置必要標題。返回承諾。在發送標頭( res.writeHead )或響應( res.send , res.end等)之前,必須調用它。
如果autoCommit加入設置為false ,則必須調用此功能。
session . hello = "world" ;
await session . commit ( ) ;
// always calling res.end or res.writeHead after the above與當前會話相關聯的唯一ID。
用於會話中間軟件的會話存儲(請參見上面的options )。
兼容的會話存儲必須包括三個功能: set(sid, session) , get(sid)和destroy(sid) 。建議使用功能touch(sid, session) 。所有功能都必須返回承諾。
請參閱MemoryStore。
打字稿: SessionStore類型可用於幫助實施:
import type { SessionStore } from "next-session" ;
class CustomStore implements SessionStore { }要使用Express/Connect商店,您必須合格get , set , destroy ,並且(如果存在) touch方法,可能使用util.promisify 。
我們將util promisifyStore包括在next-session/lib/compat中以做到這一點:
import nextSession from "next-session" ;
import { promisifyStore } from "next-session/lib/compat" ;
import SomeConnectStore from "connect-xyz" ;
const connectStore = new SomeConnectStore ( ) ;
const getSession = nextSession ( {
store : promisifyStore ( connectStore ) ,
} ) ;如果連接商店具有以下模式,則可以使用next-session/lib/compat的expressSession 。
const session = require ( "express-session" ) ;
const RedisStore = require ( "connect-redis" ) ( session ) ;
// Use `expressSession` from `next-session/lib/compat` as the replacement
import nextSession from "next-session" ;
import { expressSession , promisifyStore } from "next-session/lib/compat" ;
import RedisStoreFactory from "connect-redis" ;
import Redis from "ioredis" ;
const RedisStore = RedisStoreFactory ( expressSession ) ;
export const getSession = nextSession ( {
store : promisifyStore (
new RedisStore ( {
client : new Redis ( ) ,
} )
) ,
} ) ; 請參閱我的貢獻。
麻省理工學院