Express-session:如何添加用户详细信息以表达会话 Typescript
Express-session: How to add user detail info to express session TypesScript
嘿,所以我尝试使用 express-session
和 connect-mongodb-session
,TypeScript Express/Node Api 现在我想做的是当用户登录时我将使用 express-session 制作该 cookie 并自动将该 cookie 保存到 MongoDB。现在我遇到的问题是我想向该会话添加详细信息,即用户的信息,以便在坚持用户时我知道他们的用户名等...
现在当不使用TypeScript时,我可以简单地做这样的事情来将用户详细信息添加到正在实例化的会话中:
request.session.user = {username:'John', id='97y9797977c9q7dw7y9qw7d9721'}
但是现在在使用 TypeScript 时,当我尝试执行与上述相同的操作时遇到以下错误:\
- 错误:属性 'user' 在类型 'Session & Partial'
上不存在
代码如下: 这是我对 express-session
和 connect-mongodb-session
的设置
const store = MongoStore(expressSession);
const mongoURI = process.env.mongoURI;
const mongoStore = new store({
collection: 'usersessions',
uri: mongoURI,
expires: 10 * 60 * 60 * 24 * 1000
});
app.use(
expressSession({
name: '_sid',
secret: process.env.session_secret,
resave: false,
saveUninitialized: false,
store: mongoStore,
cookie: {
httpOnly: true,
maxAge: 10 * 60 * 60 * 24 * 1000,
secure: process.env.NODE_ENV === 'production'
}
})
);
下面的代码是我的登录方法控制器
SignIn(request: Request, response: Response) {
const form = new Formidable.IncomingForm();
try {
form.parse(request, async (error, fields, files) => {
if (error) {
return response.status(500).json({
msg: 'Network Error: Please try again later'
});
}
const { username, password } = fields;
if (!username || !password) {
return response.status(400).json({ msg: 'All fields are required' });
}
const user: any = await userModel.findOne({
usernam: username
});
if (!user) {
return response.status(404).json({
msg: 'Account with this username does not exist'
});
}
const hashedPassword = user.password;
const isPasswordValid = await Bcrypt.compare(password, hashedPassword);
if (!isPasswordValid) {
return response.status(400).json({ msg: 'Invalid credentials' });
}
const isUserSessionExisting = await userSession.findOne({
'session.user.username': username
});
if (isUserSessionExisting) {
return response
.status(200)
.json({ msg: 'Account already logged in' });
}
const userSessionObj = {
username: user.username,
id: user._id
};
request.session.user = userSessionObj; //This is where the error is coming
return response.status(200).send(request.sessionID);
});
} catch (error) {
return response
.status(500)
.json({ msg: 'Network Error: Please try again later' });
}
}
我该如何解决这个问题
您有 2 种方法来声明会话。
import {Request} from "express"
type Req= Request & { session: Express.Session }; // this will be merges
或
declare global {
namespace Express {
interface Request {
// currentUser might not be defined if it is not logged in
session: Express.Session;
}
}
}
这是会话界面:
interface Session extends SessionData {
id: string;
regenerate(callback: (err: any) => void): void;
destroy(callback: (err: any) => void): void;
reload(callback: (err: any) => void): void;
save(callback: (err: any) => void): void;
touch(): void;
cookie: SessionCookie;
}
如您所见,没有用户 属性。因为通常我们会在 cookie 中存储一个唯一标识符,即数据库 id。因为将来可以更改用户名,但用户的数据库 ID 或者如果您正在进行 google oauth 身份验证,用户的 google id 不会更改。存储 id 就足够了。但是,如果您仍想将用户对象附加到会话,请创建一个新的用户界面
interface User{
username: string;
id:string
}
type NewSession=Express.Session & User
declare global {
namespace Express {
interface Request {
// currentUser might not be defined if it is not logged in
session: NewSession;
}
}
}
嘿,所以我尝试使用 express-session
和 connect-mongodb-session
,TypeScript Express/Node Api 现在我想做的是当用户登录时我将使用 express-session 制作该 cookie 并自动将该 cookie 保存到 MongoDB。现在我遇到的问题是我想向该会话添加详细信息,即用户的信息,以便在坚持用户时我知道他们的用户名等...
现在当不使用TypeScript时,我可以简单地做这样的事情来将用户详细信息添加到正在实例化的会话中:
request.session.user = {username:'John', id='97y9797977c9q7dw7y9qw7d9721'}
但是现在在使用 TypeScript 时,当我尝试执行与上述相同的操作时遇到以下错误:\
- 错误:属性 'user' 在类型 'Session & Partial' 上不存在
代码如下: 这是我对 express-session
和 connect-mongodb-session
const store = MongoStore(expressSession);
const mongoURI = process.env.mongoURI;
const mongoStore = new store({
collection: 'usersessions',
uri: mongoURI,
expires: 10 * 60 * 60 * 24 * 1000
});
app.use(
expressSession({
name: '_sid',
secret: process.env.session_secret,
resave: false,
saveUninitialized: false,
store: mongoStore,
cookie: {
httpOnly: true,
maxAge: 10 * 60 * 60 * 24 * 1000,
secure: process.env.NODE_ENV === 'production'
}
})
);
下面的代码是我的登录方法控制器
SignIn(request: Request, response: Response) {
const form = new Formidable.IncomingForm();
try {
form.parse(request, async (error, fields, files) => {
if (error) {
return response.status(500).json({
msg: 'Network Error: Please try again later'
});
}
const { username, password } = fields;
if (!username || !password) {
return response.status(400).json({ msg: 'All fields are required' });
}
const user: any = await userModel.findOne({
usernam: username
});
if (!user) {
return response.status(404).json({
msg: 'Account with this username does not exist'
});
}
const hashedPassword = user.password;
const isPasswordValid = await Bcrypt.compare(password, hashedPassword);
if (!isPasswordValid) {
return response.status(400).json({ msg: 'Invalid credentials' });
}
const isUserSessionExisting = await userSession.findOne({
'session.user.username': username
});
if (isUserSessionExisting) {
return response
.status(200)
.json({ msg: 'Account already logged in' });
}
const userSessionObj = {
username: user.username,
id: user._id
};
request.session.user = userSessionObj; //This is where the error is coming
return response.status(200).send(request.sessionID);
});
} catch (error) {
return response
.status(500)
.json({ msg: 'Network Error: Please try again later' });
}
}
我该如何解决这个问题
您有 2 种方法来声明会话。
import {Request} from "express"
type Req= Request & { session: Express.Session }; // this will be merges
或
declare global {
namespace Express {
interface Request {
// currentUser might not be defined if it is not logged in
session: Express.Session;
}
}
}
这是会话界面:
interface Session extends SessionData {
id: string;
regenerate(callback: (err: any) => void): void;
destroy(callback: (err: any) => void): void;
reload(callback: (err: any) => void): void;
save(callback: (err: any) => void): void;
touch(): void;
cookie: SessionCookie;
}
如您所见,没有用户 属性。因为通常我们会在 cookie 中存储一个唯一标识符,即数据库 id。因为将来可以更改用户名,但用户的数据库 ID 或者如果您正在进行 google oauth 身份验证,用户的 google id 不会更改。存储 id 就足够了。但是,如果您仍想将用户对象附加到会话,请创建一个新的用户界面
interface User{
username: string;
id:string
}
type NewSession=Express.Session & User
declare global {
namespace Express {
interface Request {
// currentUser might not be defined if it is not logged in
session: NewSession;
}
}
}