honojs / hono

Web framework built on Web Standards
https://hono.dev
MIT License
18.9k stars 537 forks source link

setSignedCookie is not setting up the cookie , local host #3421

Open pranaydwivedi444 opened 1 week ago

pranaydwivedi444 commented 1 week ago

What version of Hono are you using?

4.5.11

What runtime/platform is your app running on?

Cloudfare workers

What steps can reproduce the bug?

I try to sign the cookie , it does return token and everything , but when i try to check it in browser , it doesn't show me cookie in application tab via localhost , and says authorization error I am working on a backend using Hono, JWT, and signed cookies. When a user signs in, I generate a JWT token and set it as a signed cookie using the following code:

c``` onst jwt = await sign({ id: user.id }, c.env.JWT_SECRET); const cookie_secret = c.env.COOKIE_SECRET; console.log(jwt); await setSignedCookie(c, "bearer_token", jwt, cookie_secret, { expires: new Date(Date.now() + 7 24 60 60 1000), // Cookie expiry (1 week) httpOnly: true, // Only accessible via HTTP (prevents JavaScript access) sameSite: "None", // Allows cross-site cookies }); return c.json({ message: "successfully signed in", success: true });


### What is the expected behavior?
I expect the signed cookie to be set in the browser (visible in the Application > Cookies tab) after signing in, and for it to be automatically sent with subsequent API requests. However, after signing in:

The cookie doesn't appear in the browser's Application tab. I get a 401 Unauthorized error when trying to make authenticated requests to the API, indicating the token is missing or not being sent. What I've Tried:

Checked the logs: The JWT is being correctly generated, but it isn't appearing as a cookie in the browser. Cookie options: I added the httpOnly: true flag to prevent JavaScript access and sameSite: "None" to allow cross-site requests (since my frontend and backend are on different origins during development: localhost and 127.0.0.1). CORS handling: My frontend uses axios to make requests with withCredentials: true for cookies, and I’ve configured CORS on the server.

### What do you see instead?

_No response_

### Additional information

_No response_
yusukebe commented 1 week ago

Hi @pranaydwivedi444

I think the screenshot says all of the things:

CleanShot 2024-09-20 at 20 08 43@2x

It's not a bug.

pranaydwivedi444 commented 6 days ago

https://medium-blog-worker-serverless.vercel.app/blog/all I have deployed it , here is my front end , here is my backend , https://backend.pranaydwivedi444.workers.dev/ I still can't understand the issue why the CORS error Post Man easily can run this

app.post("/signup", async (c) => {
  //fetching body
  const body = await c.req.json();
  const prisma = c.get("prisma");
  const { success } = signupInput.safeParse(body);
  if (!success) {
    return c.text("invalid inputs", 411);
  }
  //create user in db
    const existingUser = await prisma.user.findUnique({
      where: { email: body.email },
    });

    if (existingUser) {
      return c.json({ error: "User already exists" }, 409); // Conflict status code
    }

  try {
    const user = await prisma.user.create({
      data: {
        email: body.email,
        name: body.name || " ",
        password: body.password,
      },
    });
    const secret = c.env.JWT_SECRET;
    const JWT = await sign({ id: user.id }, secret);
    const cookie_secret = c.env.COOKIE_SECRET;
    await setSignedCookie(c, "bearer_token", JWT, cookie_secret, {
      expires: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
      sameSite: "None",
      secure: true,
      httpOnly: true,
    });
    // return jwt token
    return c.json({
      message: "successfull signed in",
      success : true,
    });
  } catch (err) {
    c.status(403);
    return c.json({ error: `error while signingup + ${err}` });
  }
});

app.post("/signin", async (c) => {
  const prisma = c.get("prisma");
  const body = await c.req.json();
  const { success } = signinInput.safeParse(body);
  if (!success) {
    return c.text("invalid inputs", 411);
  }
  const user = await prisma.user.findUnique({
    where: {
      email: body.email,
      password: body.password,
    },
  });

  if (!user) {
    c.status(403);
    return c.json({ error: "user not found" });
  }

  const jwt = await sign({ id: user.id }, c.env.JWT_SECRET); 
  const cookie_secret = c.env.COOKIE_SECRET;
  await setSignedCookie(c, "bearer_token", jwt, cookie_secret, {
    expires: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
  });
  return c.json({ message :"successfully signed in ", success: true });
});

Here is my auth middleware :

export const authMiddleware: MiddlewareHandler = async function (c, next) {
  try {
    // const headerToken = c.req.header("Authorization") || "";
    // const token = headerToken.split(" ")[1];
    const cookie_secret = c.env.COOKIE_SECRET;
    const token = await getSignedCookie(c, cookie_secret, "bearer_token");
    if (!token) {
      c.status(401);
      return c.json({
        message: "Tokken missing",
      });
    }

    const secret = c.env.JWT_SECRET;
    const response = await verify(token, secret);
    if (response.id) {
      c.set("authorId", response.id);
      await next();
    }
  } catch (error) {
    c.status(401);
    return c.json({
      message: "Tokken error" + error,
    });
  }
};

I am using axios to send request

async function handleAPIBlogRequest(url: string) {
  try {
    const response = await axios.get(`${backendUrl}/${url}`, {
      withCredentials: true,
    });
    return response.data;
  } catch (error) {
    throw error;
  }
}
yusukebe commented 6 days ago

@pranaydwivedi444

It's difficult to run your code on my machine. Please provide a minimal project that does not use Prisma, Zod, or some libraries. If not, I'll close this issue.