我正在使用Apollo-Server-Express将身份验证令牌从后端传递到前端。除非禁用“阻止跨站点跟踪”选项,否则我可以在Chrome上登录,但不能在Safari上登录。
我知道Safari现在默认情况下会阻止所有第三方cookie,但是我相信我会遵循下面复制的here概述的开发者选项1。
选项1:OAuth 2.0授权,通过该授权域,身份验证域(在您的情况下为希望使用Cookie的第三方)将授权令牌转发到您使用的网站,您可以使用该网站来与服务器建立第一方登录会话设置安全和HttpOnly Cookie。
如何让Safari知道我正在遵循正确的身份验证方法?
前端:
return new ApolloClient({
uri: "https://latinconexiones-yoga-stg.herokuapp.com",
request: (operation) => {
operation.setContext({
fetchOptions: {
credentials: "include",
},
headers,
});
},
index.js
var corsOptions = {
origin: "https://latinconexiones-next-stg.herokuapp.com",
credentials: true, // <-- REQUIRED backend setting
};
app.use(cors(corsOptions));
// Use express middleware to handle cookies (JWT)
app.use(cookieParser());
// decode JQT so we can get userId on each request
app.use((req, res, next) => {
const { token } = req.cookies;
if (token) {
const { userId } = jwt.verify(token, process.env.APP_SECRET);
// put user Id onto the request for future requetss to access
req.userId = userId;
}
next();
});
app.use(async (req, res, next) => {
// if they aren't logged in, skip this
if (!req.userId) return next();
const member = await db.query.member(
{ where: { id: req.userId } },
"{ id, permissions, email, name }"
);
req.member = member;
next();
});
// start it!
server.applyMiddleware({
app,
path: "/",
cors: false,
});
app.listen({ port: process.env.PORT }, () =>
console.log(`? Server ready at http://localhost:${process.env.PORT}`)
);
登录突变
async signin(parent, { email, password }, ctx, info) {
// 1. check if member with that email exists
const member = await ctx.db.query.member({ where: { email } });
if (!member) {
throw new Error(`No member found for email ${email}`);
}
// 2. check password is correct
const valid = await bcrypt.compare(password, member.password);
if (!valid) {
throw new Error(`Invalid Password`);
}
// 3. create JWT token
const token = jwt.sign({ userId: member.id }, process.env.APP_SECRET);
// 4. set the cookie
ctx.res.cookie("token", token, {
httpOnly: true,
maxAge: 1000 * 60 * 60 * 24 * 365, // 1 year cookie
secure: true,
sameSite: "none",
});
// 5. return the member
return member;
},