I'm starting to learn Play framework with Scala and I'm trying to set the session cookie.
I have the play.crypto.secret config set and also the settings for the cookie like this
play.http {
session {
httpOnly = true
domain = "localhost"
}
}
Is it normal that I see the content of the cookie in the console without problems?
for example:
As mentioned in official Play documentation, play.crypto.secret is used for signing session cookies and CSRF tokens. That's means that you will see cookie values on a client side, but they will be encrypted with the secret key.
No, the cookie is not encrypted. It is signed, meaning that part of the cookie (or a separate cookie) contains a signature value calculated using the cookie value itself and the secret key.
Related
I'm trying to hook up a Strapi backend to a SvelteKit frontend, and stuck on how to persist user login state so that everything doesn't just reset on refresh, or when navigating to a new page. I've tried:
Storing the jwt and user object issued by Strapi in localStorage and initializing the Svelte store with it. Seemed like I was getting close, but a) I couldn't do export const user = writable(localStorage.user) because that code was running in the browser, and I couldn't wrap it in an if (browser) {...} because import and export can only appear at the top level. Also tried a function in hooks.js to read the contents of localStorage and update the store, but it seems that functions getting called from there run on the server, even if it's the same function that works to access localStorage on login... and plus b) from what I gather, storing jwt's in localStorage is insecure.
Storing the jwt and user object in an http only cookie. Cookies and http headers seem really confusing, and I had a hard time manipulating them to store the jwt and put it in each header. But I think what really stumped me was essentially the same SSR issue of never knowing essentially how to successfully interface between the client and server. I.e. if (browser) {...} never seemed to work, or I couldn't get it to, anyway. (Happy to provide more code details on what I tried here if needed. It's a mess, but it's saved in git.)
I know this is a thing every app that has users needs to do, so I'm sure there's a way to do it in SvelteKit. But I can't find anything online that explains it, and I can't figure it out from the official docs either.
So am I missing something easy? (Probably.) Or is there a tricky way to do this?
For a SvelteKit SPA authenticating to Strapi, here's the happy path flow I would use:
SvelteKit page /routes/login.svelte collects the username (identifier) and password and a button's on:click handler posts those values via fetch to your own /routes/auth.js:post() endpoint. Why? Because now your server's endpoint is handling the login on behalf of the user so you can set an httpOnly cookie in the response.
In your auth.js endpoint post() method, you will want to do a few things:
Use fetch to post identifier and password to Strapi authentication (http://localhost:1337/auth/local) to get the JWT (response.body.jwt)
Use fetch to get user info from Strapi (http://localhost:1337/users/me). In the get, add a header called 'Authentication' with a value of 'Bearer ' + the JWT you just received from Strapi in the previous step
Return the user info from the response from Strapi and pass it back to your client in the response.body
Set a header httpOnly cookie with the value of the JWT.
Back on the client in the last part of the login button's on:click handler, take the user info from res.json() and put it in a writeable store called user or in the SvelteKit session store...
import { session } from '$app/stores'
...
const loginClickHandler = async () => {
...
const fromEndpoint = await res.json()
session.set({ user: fromEndpoint.user })
}
At this point, you have the user information persisted client-side and the JWT as an httpOnly cookie that can't be read or modified by client-side JavaScript code. Each request you make to your own server's pages or endpoints will send the JWT cookie along.
If you want to logout, call an endpoint on your server (/auth/logout) that sets the existing jwt cookie to have an Expires based on the current date/time:
response.headers['Set-Cookie'] = `jwt=; Path=/; HttpOnly; Expires=${new Date().toUTCString()}`
You would also want to clear the user object in your store (or the session store).
The main takeaway for the above example is that your client would never directly talk to Strapi. Strapi's API would be called only by your SvelteKit server's endpoints. The httpOnly jwt cookie representing your session with Strapi would be included in every request to your server's endpoints to use/validate with Strapi's API (or delete if expired or the user logged out).
There are lots of other approaches but I prefer this one for security reasons.
I have a flask API, with jwt authentication, on a httponly cookie. I installed interceptor, added the domain(with HTTPS) to the list, and enabled the requests and cookies interception.
but still,
how do I make postman send the cookie I got from logging in to the server? usually, with a simple front-end, it just happens, so I didn't think about it.
all the methods I found in postman documentation, including specifying the value with the token, but I don't have it, since I can't access the httponly cookie. (or can I?)
must I access the cookies? can it be done automatically like simply sending requests from the front-end?
any guidance will be appreciated
After a full evening of research, I did two things to make it work -
in the login request, I added a "test" script(a post-request script in postman), with the following code:
const csrf_token = pm.response.headers.get("set-cookie");
const edited_token = csrf_token.split(/[;=]/)[1];
pm.environment.set("X-CSRF-TOKEN", edited_token);
console.log(csrf_token.split(/[;=]/)[1]);
First, I got the cookie from the response, and then used a regex to separate only the token value, and set it as an environment variable. this way, I could add it as a header later, for accessing protected URLs.
The second step was to add a pre-scrit in any request with a protected URL -
in the pre-request tab, I added the following:
pm.request.headers.add({
key: 'X-CSRF-TOKEN',
value: pm.environment.get("X-CSRF-TOKEN")
});
Which only added the same token I took earlier from the "X-CSRF-TOKEN" environment variable and set it to the header.
Mission accomplished :)
I hope it will help others who bumped into this
I am looking to integrate Cookie based authentication in my FastAPI App. I want the same to work seamlessly with swagger as well.
I want to have a route (eg: /login) which sets my browser cookies. All other protected route uses Depends in the decorator to verify the key present in cookie. How do I get this to work with OpenAPI authorize button?
Important factor here is integration with Swagger/OpenAPI docs auto generated by FastAPI.
You can have a look at the fastapi-users module that implements a cookie-based authentication (it implements other user-management-related stuff as well, so it is worth a look anyway!).
According to the coookie docs:
Configuration
from fastapi_users.authentication import CookieAuthentication
SECRET = "SECRET"
auth_backends = []
cookie_authentication = CookieAuthentication(secret=SECRET, lifetime_seconds=3600)
auth_backends.append(cookie_authentication)
As you can see, instantiation is quite simple. You just have to define
a constant SECRET which is used to encode the token and the lifetime
of the cookie (in seconds).
You can also define the parameters for the generated cookie:
cookie_name (fastapiusersauth): Name of the cookie.
cookie_path (/): Cookie path.
cookie_domain (None): Cookie domain.
cookie_secure (True): Whether to only send the cookie to the server via SSL request.
cookie_httponly (True): Whether to prevent access to the cookie via JavaScript.
cookie_samesite (lax): A string that specifies the same site strategy for the cookie. Valid values are 'lax', 'strict' and 'none'.
Defaults to 'lax'.
Then you can login with a POST request on the /login endpoint and set the cookie on the browser.
I found no info on the auto-OpenAPI integration, but since login is setting the cookie on the browser, you can log in once and then use the API.
I am new to RESTful services testing and got stuck where to establish connection to end point I need to pass Cookie. I have the parameter and Value but not sure how to pass Cookie manually (not through header or Groovy script) while hitting request.
TL;DR
Cookies are nothing but a header with a name cookie and header-value in a format name=value; anothername=anothervalue; yetanotherone=yetanothervalue;, as far as an http-request is concerned
Read On
From https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cookie
The Cookie HTTP request header contains stored HTTP cookies previously
sent by the server with the Set-Cookie header.
The Cookie header is optional and may be omitted if, for example, the
browser's privacy settings block cookies.
How to send Cookie
Just like any other header. Only condition is, Header name should be cookie and Header-value should be in name=value; anothername=anothervalue; yetanotherone=yetanothervalue; format.
Curl
curl -v --cookie "USER_TOKEN=my-most-secure-session-id" http://localhost:8080/
If you want your curl to read the cookie file and send it
use curl -c /path/to/cookiefile http://yourhost/
More here : https://curl.haxx.se/docs/http-cookies.html
How to send it using SoapUI
Sending cookie as request header in SOAP UI request for rest web service
Establish User session (Login) using chrome or firefox and goto the developer tab and copy the cookie value and send that along with your soapUI request as a header. (Congrats, you are hijacking your own session)
For any test that you need to pass the cookie around, in soapUI, go to the testcase options and turn on "maintain HTTP session".
http://www.soapui.org/soapui-projects/form-based-authentication.html
This is my google chrome developer tab which shows stackoverflow page's requestheaders
Just send the http header
Cookie: name=value
To the server
I am trying to communicate to a RESTFul API using MATLAB. the API uses session cookie to remember the user. My MATALB is 2015b and as long as I know, it does not support the new HTTP Interface.
my problem is that using the webread and webwrite functions in MATLAB, the session cookie is not attached to the request and therefore each time server generates a new session.
I tried to use urlread2 to read the session cookie and generate a new one with the same content, for sending back to the server, but the session cookie is HTTPOnly and therefore my generated cookie is not valid for the server.
Can anyone help me with an idea or solution? does MATLAB 2016b forward the session cookie automatically (using HTTP interface)?
I was able to find a solution to this problem:
first problem is to get the cookie info in MATLAB. versions earlier than 2016b are probably not able to do it, so I had to use for it:
[output,extras] = urlread2('http://www.example.com/','GET');
cookie = extras.firstHeaders.Set_Cookie; % make sure to get the content of the right session cookie
now that we have the cookie, let's add it to the |weboptions| like this:
opts = weboptions('KeyName','Cookie','KeyValue',cookie);
and now simply every time that you use |webread| or |webwrite| , attach the |opts| to it:
response = webread('http://www.example.com/',opts);
But using this method, it is very easy to do XSS attacks on websites that use HTTPOnly cookies for session management! unlike all the web browsers, matlab allows you to edit or create HTTPOnly cookies! more info here