What SESSION_DOMAIN should I use if I'm using Laravel Sail? - laravel

I want to use Nuxt.js for my frontend and laravel sanctum as my backend authentication provider. How should I set the SESSION_DOMAIN key in the .env file in my laravel project.
Also should I edit anything in the server object part in the nuxt.config.js file to make this work?

When you use Sanctum with SPA, such as Nuxt, you've the option to use either API or cookies/sessions. If your application is a first-party application on same top level domain, Laravel recommends to use cookie based approach so you can take advantage of CSRF protection. Axios and Angular Http libraries handles CSRF out of the box, so you don't have to worry too much about handling the requests headers [1].
In your case, I assume your application is first party and is on same top level domain. So your SESSION_DOMAIN value would be for example .domain.com. Also you'll need to set SANCTUM_STATEFUL_DOMAINS=domain.com as well. Usually your SESSION_DOMAIN will have just the main domain your application uses on, while SANCTUM_STATEFUL_DOMAINS will have all the subdomains (if any), that your frontend uses.

To work with Sanctum, we should be familiar with a few things first. We must use our SPA and API backend on the same domain, like frontend on domain.com and API on api.domain.com. We can not set frontend on domain.com and backend (API) on another-domain.com. The client must be able to include cookies with each request being sent to the backend.
session domain is the front-end domain name without protocol and port.
When you are working on local you must set it to localhost and when you are working on server you must set the domain name.
please follow this example of nuxt-laravel-sanctum-auth

Related

Is it safe to share authentication state via reactive global store in Vue 3?

I'm building a CMS with vue 3 and want to know if using global store store.store.auth = false/true is a secure way of rendering in/out components that are supposed to be seen only by authenticated users. It goes like this:
User enters credentials in login form
Credentials are sent via HTTP request to backend and checked by laravel sanctum
Response arrives in frontend which sets store.store.auth = true
Components and routes that are supposed to be seen only by authenticated users are rendered via v-if
Is this a secure approach or can it be improved?
The security, in this case, depends almost entirely the backend.
Sanctum does not use tokens of any kind. Instead, Sanctum uses Laravel's built-in cookie based session authentication services. Typically, Sanctum utilizes Laravel's web authentication guard to accomplish this. This provides the benefits of CSRF protection, session authentication, as well as protects against leakage of the authentication credentials via XSS.
src
It seems like sanctum handles the authentication, so you should be fine as long as
store.store.auth value is kept up to date, and
the API does it's own authentication and authorization.
Because the entirety of the application is visible through the js source someone could potentially modify state and display options that they shouldn't see. This would be really-really difficult to prevent in SPA, that's why it is paramount that the backend handles this correctly.
You may be able to use code splitting, to prevent loading parts of the application that require authentication, but this is not security measure.

Can we remove using cookie from laravel sanctrum?

Is there way to remove cookie based feature from laravel sanctum and only use Authorization Bearer token way.
As, by default it sets and check through cookie and this feature don't work when API is deployed with different server then front-end.
Yes, it is possible.
\Laravel\Sanctum\Guard goes through config sanctum.guard, default value is web, so you can set this config in your config/sanctum.php file to whatever suits your need.
Eventually, you can change your web middleware group, if your SPA is the only GUI client.
If any of mentioned options is viable or smart is another question, to which I'd reply: "nope, configure your app properly to send and accept security headers and/or cookies with cors settings fitting your needs."

How to prevent exposing client secret when using laravel passport?

I'm trying to implement laravel's passport to protect my api routes and I have a case where the route should be inaccessible unless it is called by an authorized application. I am trying to use Client Credentials Grant Tokens and using postman I am able to generate an access token, which then I can use for access authorization.
The problem is - I don't understand how should I safely use this with Vue and axios. I have my component in which I need to call this api, I can of course set a form body including all the necessary fields (client_id, client_secret and grant_type) but that would mean that anyone could just open up chrome dev tools and search for client_secret in the source and they would get the hardcoded client secret, which would grant them access to the api. What is the right way to do this?
It depends on how you use your Vue frontend.
If it is a frontend mostly for your own site, but sometimes needs to access an external API, than you should have your backend make the API calls and store secrets there.
If you are developing a Vue frontend dedicated to the external API, but running on a different domain, you could go for the PKCE option: https://laravel.com/docs/8.x/passport#code-grant-pkce
If you have a frontend on the same domain as the API, use the CreateFreshApiToken option provided by Laravel passport.

Protection of API against direct access

I have separate backend and frontend. However, they run on the same server (this may change in the future). The backend serves as an api and is powered by Laravel. Frontend by Nuxt (Vue).
I wish only my Nuxt application could access the api. How can I configure Laravel to only return data if the request comes from a Nuxt application?
I thought about adding a special token to requests, but the user will be able to check what request is coming out and capture the token. Can anyone give me ideas how this can be solved?
You must be knowing about CORS. So in your Laravel Server, allow requests from only the frontend server's domain like this:
Access-Control-Allow-Origin: https://www.example.com
Simplest solution would be to add serverMiddleware in the nuxt project and route all the requests to the "real" api through it. Clients will hit the internal nuxt api and they will not be able to see the actual request made to the real api. There you can also add the token you are talking about for extra layer of security.

Sanctum CSRF Cookie not sent when accessing from domain

I'm trying to build an app that will consume Laravel APIs and I'm trying to use Sanctum for authentication. I've check a whole bunch of videos and tutorials and one thing I've noticed is that they are all using localhost or 127.0.0.1 for demonstration purposes.
However, one thing I'm missing out is actually figuring out how to work with the domains.
In my case, I'm using Valet to serve the laravel app. And after configuring everything needed for sanctum, I'm left struggling with getting the CSRF cookie when request is sent to https://domain.test/sanctum/csrf-cookie.
In Postman I'm getting no cookies
I started going nuts, and then I tried simple php artisan serve and made a request to http://127.0.0.1:8000/sanctum/csrf-cookie and by magic I got the cookies
Any explanation why this might happen will be great.
To note, I've set SESSION_DOMAIN and SANCTUM_STATEFUL_DOMAINS in my env file to include both localhost and domain.test.
You need to add session domain in the .env file
SESSION_DOMAIN=.domain.test
[and don't forget to add . (dot) before domain]

Resources