DEV Community

Cover image for Building Vue.js Client SPA Token-Based Authentication with Laravel Sanctum

Building Vue.js Client SPA Token-Based Authentication with Laravel Sanctum

Roman Paprotsky on March 23, 2020

Authentication systems are a vital part of most modern applications, and should thus be appropriately implemented. In this article, you will learn...
Collapse
 
derekbliss profile image
Derek Bliss

Great Article! I am having an issue with CORs. Everything works great locally but when I upload my backend to api.example.com and my frontend to example.com I get this issue.

Access to XMLHttpRequest at 'api.example.com/api/banlist/fetch' from origin 'example.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Collapse
 
romanpaprotsky profile image
Roman Paprotsky

Have you tried to add SANCTUM_STATEFUL_DOMAINS=127.0.0.1 to .env file on the server?

Collapse
 
derekbliss profile image
Derek Bliss

Yes this is set in the .env file.

Thread Thread
 
derekbliss profile image
Derek Bliss

It is set but still same error. Could it be because the API and frontend are in different directories? I have tried just about everything and I am still getting the same error. I am almost to the point of moving the frontend into Laravel.

Thread Thread
 
romanpaprotsky profile image
Roman Paprotsky • Edited

Have you set baseURL and headers in main.js?

Vue.prototype.$http = axios
Vue.prototype.$http.defaults.baseURL = 'https://example.com/api'
Vue.prototype.$http.defaults.headers.post['Content-Type'] = 'application/json'
Thread Thread
 
derekbliss profile image
Derek Bliss

Just tried this and same error.

Thread Thread
 
romanpaprotsky profile image
Roman Paprotsky

Could you share your repositories? I could have a look tomorrow. My email address is roman@paprotsky.com

Thread Thread
 
derekbliss profile image
Derek Bliss

Cool thank you. I sent you an email.

Thank you!

Thread Thread
 
eugenevdm profile image
Eugene van der Merwe

Hi @derek how was this problem solved?

Thread Thread
 
ingenmanuelrojas profile image
Enmanuel Rojas

hi, did you manage to solve the problem?

Collapse
 
morris14 profile image
morris14 • Edited

Great post! I noticed you store the token in localstorage, is this safe? I always thought this was an insecure way of storing sensitive data seeing as the token is more or less the users username/password combo?

Collapse
 
onegeco profile image
OneGeco

Hi @moris14 it's really wrong storing sensitive data in LocalStorage meanwhile i haven't seen any article on a better way to go about this, please share if you have any.

Collapse
 
gweinxx profile image
gweinxx • Edited

(Based on my app)

U can verify token owner by comparing ip address, browser: version, device, custom cookies, etc

  1. You need to track users here
  2. Token hasOne Login (Ip address, device platform, browser name, browser version, etc)
  3. If you still need to verify the user, add password verification feature, for worse scenarios like:
  4. Token is not being used for (x) days
  5. Tracker result doesn't match token login's information (#2)
  6. Token exist, but custom cookies is expired / missing

With this feature, personally I can offer the user to see, what devices are they are logged in, logout from specific device / all devices, etc

If anyone got better idea, I would like to know and learn :D

  • Note: sorry for bad english
Collapse
 
dominiquebureau profile image
Dominique

Thanks for this tutorial. I had tried to do the same with React. And I had never managed to do it. VueJs is much simpler!

A little evolution please. Imagine an 'about2' route. If I try to access it without being logged in, the app sends me back to the login page. Perfect ! But then, how can I be redirected automatically to 'about2' and not to 'about'? I guess I must store the target route name in the store but after ?

thanks again for this tutorial.

Collapse
 
romanpaprotsky profile image
Roman Paprotsky

Hi Dominique,

I guess it definitely make sense to store the target route name in the store and check it out in the login() method in the ..src/views/Login.vue view before this.$router.push({ name: 'About' })

Collapse
 
romanpaprotsky profile image
Roman Paprotsky

This Vue Screencasts video can be useful.

Collapse
 
ellis22 profile image
Ellis

Nice tutorial! The way it is written it is easy to understand. Thanks.
I also recommend to watch this ( youtube.com/watch?v=8Uwn5M6WTe0 ) video tutorial, here Laravel Sanctum is explained step by step in detail.

Collapse
 
defji profile image
Balázs Györkös

Hi! Nice tutorial! How to use axios in other compoents for further api requests?

Collapse
 
romanpaprotsky profile image
Roman Paprotsky

That's a good question, Balázs!

You can add in main.js:

Vue.prototype.$axios = axios
Enter fullscreen mode Exit fullscreen mode

After that in components you can write:

$axios.get('/items')
  .then(function (response) {
    console.log(response)
  })
Enter fullscreen mode Exit fullscreen mode
Collapse
 
ohidurbappy profile image
Ohidur Rahman Bappy • Edited

From child component I had to refer using this keyword

this.$axios.get('/items')
  .then(function (response) {
    console.log(response)
  })
Enter fullscreen mode Exit fullscreen mode
Collapse
 
eugenevdm profile image
Eugene van der Merwe

I really love this article! I love the style of writing, and the way to code is presented. Furthermore the way the code is presented is very clear and concise. This is a great template to get to know a number of modern day Laravel/Vue.js concepts - APIs, Sanctum, Vuex, Vue routing. It will be my go to reference going forward. Thank you!

Collapse
 
romanpaprotsky profile image
Roman Paprotsky

Thank you for the kind words, Eugene!

Collapse
 
deevannaveed profile image
Muhammad Naveed

Hey Roman, thanks for the amazing thread, can you please guide us about using the Sanctum with multiple guards e.g. Admin, User.

Collapse
 
haratmalli profile image
haratmalli

Did you find any solution related multiple guard authentication sanctum

Collapse
 
deevannaveed profile image
Muhammad Naveed

In Laravel multiple guards only work in session based auth that's why I ended up using "Token Abilities" which works fine for me, you can read more about Token Abilities in Laravel Sanctum docs, in Passport this feature is called token scopes. I hope it will help you.

Collapse
 
antoniogiroz profile image
Antonio Gil

Hi, thanks for this tutorial, but you are using tokens here, what about cookies?

Collapse
 
romanpaprotsky profile image
Roman Paprotsky

Maybe, this article could be useful for you.

Collapse
 
romanpaprotsky profile image
Roman Paprotsky

Could you clarify your question, Antonio?

Collapse
 
gcj5219 profile image
gcj

Great Article, Currently I'm doing some coding practice with the laravel socialite package using postman for api request. Do you have a written article for this kind of log in using 3rd party API like google. facebook and twitter?

Collapse
 
nicholascourage profile image
nicholascourage

Thanks for this! What should we use for SANCTUM_STATEFUL_DOMAINS=127.0.0.1 in a dockerised local dev environment?

Collapse
 
romanpaprotsky profile image
Roman Paprotsky

I don't have work experience with Laravel + Docker, sorry.

Collapse
 
nicholascourage profile image
nicholascourage

That's ok - thanks for coming back to me. I'll reply to myself and answer as and when I find out.

Collapse
 
bodrosh profile image
Bodrosh

Thanks, great article!

Collapse
 
mrdt12 profile image
Dennis Tabaldo

greate article! thanks

Collapse
 
zynth17 profile image
Christopher Reeve • Edited

thankyou for this great article!
but anyway is it safe to safe the sanctum token on the localstorage?

Collapse
 
billjustin15 profile image
billjustin

This is helpful! I would like to ask, do i need to change SANCTUM_STATEFUL_DOMAINS value if host my app?

Collapse
 
romanpaprotsky profile image
Roman Paprotsky

img

Collapse
 
nicholascourage profile image
nicholascourage • Edited

Thanks for this! What should we use for SANCTUM_STATEFUL_DOMAINS=127.0.0.1 in a dockerised local dev environment?

Collapse
 
emrecanful profile image
Emre Can Çakıroğlu • Edited

This is a great tutorial! But I have a tiny question. While setting CORs as I understand we made the api accessible from everywhere? I want my api to work only within my website, how to achieve that?

Collapse
 
romanpaprotsky profile image
Roman Paprotsky • Edited

Great question!

To make the api accessible from your site only, you have to set

 'allowed_origins' => ['http://yoursitename.com']

Screenshot

Access-Control-Allow-Origin

Collapse
 
devondahon profile image
gvi

Great article! I'm actually trying to figure out how to do the same (vue-cli as frontend and Laravel 7 as backend) with Passport (and PKCE) authentication, would you write an article about it ?

Collapse
 
romanpaprotsky profile image
Roman Paprotsky

Thank you for your feedback, gvi.
There are many articles about Laravel Passport and I don't think there is a need to have one more.
Because Laravel Sanctum was just released with new Laravel 7, there are no too much tutorials on this topic yet. That was the reason why I wrote this article. Hope it will be useful.

Collapse
 
cleo_hacker profile image
Cleo • Edited

Thank you, you have really helped. Everything worked