2

I have an API that is secured using Laravel Sanctum. In the front-end I managed to login with sanctum and a new bearer token is issued. So far so good but how can I store the token (without Vuex) to local storage and how I tell axios to use that token for any future requests ?

My code is as follows:

// AuthController.php

public function login(Request $request)
    {
        $fields = $request->validate([
            'email' => 'required|string',
            'password' => 'required|string'
        ]);

        $user = User::where('email', $fields['email'])->first();

        $token = $user->createToken('login_token')->plainTextToken;

        if (!$user || !Hash::check($fields['password'], $user->password)) {
            return response([
                'message' => 'Invalid Login Credentials'
            ], 401);
        }

        $response = [
            'user' => $user,
            'token' => $token
        ];

        return response($response, 201);
    }
// Login.vue

export default {
    methods: {
        handleLogin() {
            axios.get("/sanctum/csrf-cookie").then(response => {
                axios.post("/api/login", this.formData).then(response => {
                    if (response.status === 201) {
                        this.$router.push({ path: "/" });
                    }
                    console.log(response);
                });
            });
        }
    },
    data: function() {
        return {
            logo: logo,
            formData: {
                email: "",
                password: ""
            }
        };
    }
};

The login works fine, it is returning the expected results but I don't know how to store the generated token and how to send it to any future axios requests.

Thanks.

*** UPDATE ***

Ok so I figured it out how to send the headers and I'm doing it like so:

 axios
            .get("/api/expenses/", {
                headers: {
                    "Content-Type": "application/json",
                    Authorization: "Bearer " + "6|cnuOY69grhJiZzxEHoU74PapFkkcJeqbf3UiKx8z"
                }
            })
            .then(response => (this.expenses = response.data.data));
    }

The only remaining bit to this is how can I store the token to the local storage because right now, for testing purposes I hard coded the token.

Marian Pop
  • 361
  • 4
  • 18
  • 1
    I recommend you use cookies rather than local storage (See https://stackoverflow.com/a/44209185/7970660 for an explanation why). For cookies, you can use a package like [js-cookie](https://www.npmjs.com/package/js-cookie) to set a cookie when you receive the auth token, and then read that token when making an API request. Additionally, it looks like you are trying to use your API from your frontend? Sanctum has a built-in feature where you don't need to worry about tokens - [check out SPA Authentication](https://laravel.com/docs/8.x/sanctum#spa-authentication). – Alex T Jun 29 '21 at 17:31
  • Yeah I know it's just I wanted to make this token based auth working. And I did. Found out the response :) Thx. – Marian Pop Jun 29 '21 at 17:56

2 Answers2

2

In your Login.vue script

methods:{
        loginUser(){
                axios.post('/login',this.form).then(response =>{
                    localStorage.setItem('token', response.data.token) //store them from response
                    this.alerts = true
                this.$router.push({ name: 'Dashboard'})
            }).catch((errors) => {
                this.errors = errors.response.data.errors
            })
        },
}

In your logged in file lets call it Dashboard.vue in <script>,

data(){
      return {
          drawer: true,
          user: {roles: [0]},
          token: localStorage.getItem('token'), //get your local storage data
          isLoading: true,
      }
  },
methods: {
      getUser(){
        axios.get('/user').then(response => {
            this.currentUser = response.data
            this.user = this.currentUser.user 
        }).catch(errors => {
            if (errors.response.status === 401) {
                 localStorage.removeItem('token')
                 this.$router.push({ name: 'Login'})
            }
        }).finally(() => {
            setTimeout(function () {
                this.isLoading =  false
            }.bind(this), 1000);
        })
      },
  },

created(){
      axios.defaults.headers.common['Authorization'] = `Bearer ${this.token}` //include this in your created function
      this.getUser()  
      this.isCreated = true   
  }

I hope it works well for you

WillianBabuu
  • 427
  • 5
  • 9
1

Ok so this is how I sorted this out.

Storing the token in the local storage:

localStorage.setItem("token", response.data.token);

Using the token when sending an axios call to the api:

const token = localStorage.getItem("token");
        axios
            .get("/api/endpoint/", {
                headers: {
                    "Content-Type": "application/json",
                    Authorization: "Bearer " + token
                }
            })
            .then(response => (this.expenses = response.data));
    }
Marian Pop
  • 361
  • 4
  • 18