Safari阻止身份验证令牌

时间:2020-08-25 14:40:09

标签: node.js authentication cookies safari

我正在使用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;
  },

0 个答案:

没有答案
相关问题