- Issue created by @brianperry
- 🇮🇳India pratik_kamble Pune, India
@brianperry @CobyPear For cookie based authentication what should be parameter for object?
{type: "Cookie", credentials: {xCSRFToken: "token", value: "cookiesessionstring"}
I'm not as familiar with cookie based on in this context. I am probably misunderstanding these docs but is the username and password required credentials? https://www.drupal.org/docs/8/core/modules/rest/using-other-authenticati... →
In other words, what do we need to provide to get the cookie back? `xCSRFToken` makes sense. I don't know if we need `value` here unless we need it to pass to Drupal. I would expect `username` and `password if I understand correctly.
- 🇮🇳India pratik_kamble Pune, India
While testing on the Postman, I had to fetch the x-csrf-token from path `session/token`. Get the cookie value from the browser.
Do we expect to perform the operation to fetch x-csrf-token. and session value by calling `user/login` path with appropriate params in the code? - 🇺🇸United States brianperry
This gets tricky because the behavior varies quite a bit between server side and client side. Somewhat surprisingly, I was only able to create a functioning server side example. Apparently Cookie headers are considered forbidden response headers on the client side. Here's the server-side example I came up with:
const cookie = await fetch( "http://drupal-contributions.lndo.site/user/login?_format=json", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ name: "myusername", pass: "mypassword", }), } ).then((response) => response.headers.get("Set-Cookie")); const headers = new Headers(); if (typeof cookie === "string") { headers.append("Cookie", cookie); } // Returns 1 if user is logged in const loginStatus = await fetch( "http://drupal-contributions.lndo.site/user/login_status?_format=json", { headers, } ).then((response) => response.json()); console.log("Login Status", loginStatus); // If not authenticated, data will be an empty array. const authenticatedEndpoint = await fetch( "http://drupal-contributions.lndo.site/jsonapi/action/action", { headers, } ).then((response) => response.json()); console.log("Actions", authenticatedEndpoint);
So looping back to the original question, I think the object would probably be:
{type: "Cookie", credentials: {username: "username", password: "password"}
We would store the actual cookie value (and the csrf_token if necessary) and include it on subsequent requests.
Along the way I saw examples that suggested both including `credentials: "include",` in the fetch options object, and also `"X-CSRF-Token` in the headers (as mentioned, this is available in the login response data as csrf_token.) I didn't find either to be necessary in this example.
This was one of those things that I added based on hearing it as user feedback. I continue to be a little skeptical. What does it mean for us to add a feature like this that will likely only work reliably on the server? And since you have to pass username and password, what benefit do you really get from this compared to basic auth? I guess the credentials are only passed once rather than all the time?
I don't think this would be hard to implement, but I'm wondering if the right choice here is to postpone it from 1.0 and revive it if we get more feedback requesting it. I also wonder if people who think they want this would be better served with a JWT based solution if we can come up with one in the future.
- Status changed to Postponed
11 months ago 3:12pm 11 February 2024 - 🇺🇸United States ctrladel North Carolina, USA
Would this also postpone nice to have features for using cookie based auth to make requests? I agree in a fully decoupled scenario JWTs make a lot more sense but when looking to progressively decouple part of the admin interface cookie support is nice. Since a user logs in via Drupal to access the admin portion of the site anyways they typically will already have a cookie that can be used.
- Status changed to Active
11 months ago 11:08pm 13 February 2024 - 🇺🇸United States brianperry
> Would this also postpone nice to have features for using cookie based auth to make requests? I agree in a fully decoupled scenario JWTs make a lot more sense but when looking to progressively decouple part of the admin interface cookie support is nice.
That's a good point. We should test this progressively decoupled use case. My guess is that if it can work at all, it would 'just work' because the cookie is already set for the same site. If that doesn't work, I'm not sure what I outlined above would help either.
Un-postponing this for now as to not lose track. Would like to either test this prior to 1.0 or mark this as some kind of fast follow.
- Status changed to Fixed
9 months ago 11:55pm 31 March 2024 - 🇺🇸United States brianperry
> Would this also postpone nice to have features for using cookie based auth to make requests? I agree in a fully decoupled scenario JWTs make a lot more sense but when looking to progressively decouple part of the admin interface cookie support is nice.
Looped back to this. Confirmed that in a progressively decoupled use case the client will automatically inherit the active Drupal authentication.
I created the following JS file:
import { JsonApiClient } from "https://esm.run/@drupal-api-client/json-api-client"; const client = new JsonApiClient(window.location.origin); const actions = await client.getCollection("action--action"); console.log("This request requires authentication", actions);
And loaded that script as a module in my library:
api_client_examples: js: js/api-client-example.js: { attributes: { type: module } } dependencies: - core/drupal
In a browser window where I'm logged in, I see results for the 'action' collection. Unauthenticated in an incognito window I see no results.
As a result, I think we can close this. I'll also add this use case to the docs.
Automatically closed - issue fixed for 2 weeks with no activity.