vue.jsaxiosflask-jwt-extended

How to provide authorization header from flask api to vueJS


I am working on a login page which uses JWT for authorization. The authorization is working fine in the backend. But when I try to authorize the page using axios from VueJS, I am getting an error saying Missing authorization header. I wanna know how to pass the access token into the frontend. My python code is:

from flask import Flask,jsonify, render_template , url_for 
,redirect,session,request
from flask_sqlalchemy import SQLAlchemy

from flask_bcrypt import Bcrypt
from flask_cors import CORS

from flask_jwt_extended import create_access_token
from flask_jwt_extended import get_jwt_identity
from flask_jwt_extended import jwt_required
from flask_jwt_extended import JWTManager

app = Flask(__name__)
CORS(app, resources={r'/*': {'origins': '*'}})
# Setup the Flask-JWT-Extended extension
app.config["JWT_SECRET_KEY"] = "54\x85\xfc\x1a*Y\xae"  # Change 
this!
jwt = JWTManager(app)

db = SQLAlchemy(app)

bcrypt = Bcrypt(app)

@app.route('/')
@jwt_required()
def home():
    current_user = get_jwt_identity()
    return jsonify(logged_in_as=current_user), 200
@app.route('/login', methods=['POST'])
    def login():
    if request.method=='POST':
      mail = request.form.get("mail")
      password = request.form.get("password")
      print(mail,password)
      access_token = create_access_token(identity=mail)
      return redirect('http://localhost:8080/')


@app.route('/register', methods=['POST'])
def register():
   return redirect('http://localhost:8080/')

if __name__ == "__main__":
   app.run(debug=True)

My vue Router code is:

import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue'
import LoginView from '../views/LoginView.vue'
import RegisterView from '../views/RegisterView.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    path: '/login',
    name: 'login',
    component: LoginView
  },
  {
    path: '/register',
    name: 'register',
    component: RegisterView
  }
]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

export default router
My Home.vue is:

<template>
  <h1>{{msg}}</h1>
</template>

<script>
import axios from 'axios';
export default {
  name:'HomeView',
  data() {
    return {
        msg : ''
    }
  },
  methods: {
    getResponse() {
        const path = 'http://localhost:5000/';
        axios.get(path)
        .then((res) => {
            console.log(res.data)
            this.msg= res.data;
        } )
        .catch((err) => {
            console.error(err);
        })
    }
  },
  created(){
    this.getResponse();
  }
}
</script>

<style>

</style>

Solution

  • First of all, when the user logs in, you should store the token somewhere in your front-end code. Usually the access token is stored in Local storage with below code:

       localStorage.setItem('access_token', accessToken)
    

    For now, you've just stored the access token, so that you can access it everywhere in your website. Next, for sending the token in your future requests, you must specify the headers in your axios request and send the token with it. So first you should get the token from local storage, and then send the proper request:

    let access_token = localStorage.getItem('access_token')
    axios.request.get(path, {
            headers: {
                'Authorization': access_token
            }
          })
          .then(response => {
            console.log(response.data)
          })
    

    I hope you'll find it helpful!