Laravel Sanctum + Vue Auth

Viewed 3267

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.

2 Answers

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

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));
    }
Related