首页 > 解决方案 > 无法更新用户配置文件。(Laravel 8 和 Vue.js 2)

问题描述

我对 Laravel 和 Vue.js 很天真。我对后端使用 JWT 身份验证,对前端使用 VueX。我希望用户能够更改他们的图片、姓名和电子邮件,但是当我尝试保存时出现错误。为了您的信息,我尝试先编辑并保存姓名和电子邮件,然后更新图片。

我的个人资料页面 ,这是我收到的错误。这是我的代码:在此处输入图像描述 在此处输入图像描述

<template>
<div class="container" style="padding-top:25px">
    <div class="main-font">My Profile</div>
    <div class="d-flex row">
        <div class="col-6">
            <ValidationObserver v-slot="{ handleSubmit }">
                <form @submit.prevent="handleSubmit(updateProfile)">
                    <div class="d-flex py-4">
                        <!-- <img class="profile" src="/img/profile.jpg" alt="" > -->
                        <div>
                            <template v-if="!currentUser.profile_image_url" >
                                <img class="profile" src="/img/default.png" alt="">
                            </template>
                            <template v-else>
                                <div class="profile">{{currentUser.profile_image_url}}</div>
                            </template>
                        </div>
                        <div class="my-auto ml-5">
                            <button type="submit" class="btn upload text"><i class="fas fa-upload fa-sm pr-2"></i>Upload new picture</button>
                        </div>
                    </div>
                    <div class="form-group col-10 p-0 m-0">
                        <ValidationProvider name="Name" rules="required|alpha" v-slot="{ errors }">
                            <label  class="text">Name</label>
                            <input type="text" id="name" class="form-control form-text" placeholder="Enter your username" v-model="userForm.name">
                            <span class="error-messsage">{{ errors[0] }}</span>
                        </ValidationProvider>
                        <!-- <small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small> -->
                    </div>
                    <div class="form-group col-10 p-0 m-0 mt-4">
                        <ValidationProvider name="E-mail" rules="required|email" v-slot="{ errors }">
                            <label class="text">Email</label>
                            <input type="email" id="email"  class="form-control form-text" placeholder="Enter email" v-model="userForm.email">
                            <span class="error-messsage">{{ errors[0] }}</span>
                        </ValidationProvider>
                    </div>
                    <button type="submit" class="btn col-10 p-o save-but">SAVE CHANGES</button>
                </form>
            </ValidationObserver>
        </div>
        <div class="w-50">
            <img class="bg-img" src="/img/profile-bg.png" alt="">
        </div>
    </div>
</div>

脚本:

<script>
import { ValidationProvider, ValidationObserver, extend } from 'vee-validate/dist/vee-validate.full';

export default {

    components: {
        ValidationProvider,
        ValidationObserver,
    },

    data() {
        return {
            userForm: {
                name: '',
                email: '',  
            },
            
            error: null,
        }
    },
    watch: {

    created () {
        this.userForm = JSON.parse(JSON.stringify(this.$store.getters.currentUser));
    

    },

    computed: {          
        currentUser(){
            return this.$store.getters.currentUser;
        },
    },

   
    methods: {
        //  updateProfile (){
        //     this.$store.dispatch('updateUser'); 
        //     var _this = this;
        //         // ajax call to POST this.profile then
        //     _this.$store.commit('update', 
        //         {
        //             // name: 'currentUser',
        //             data: this.userForm
        //         })
        // },

        getUser (){
            const token = localStorage.getItem('token')
            axios.get('/api/auth/userprofile',{
                headers: {
                    Authorization: `Bearer ${token}`
                }
            })
            .then(response => {
                this.userForm= response.data.user;
                // this.userForm.email = response.data.user.email;

            })
        },

        updateProfile () {
        axios.put('/update-profile',
            {
                name: this.userForm.name,    
                email: this.userForm.email,
            })
            .then(response => {
                this.userForm.name = response.data.name;
                this.userForm.email = response.data.email; 
                swal({
                    icon: "success",
                    text: "Update Succesfully!",
                });   
            })
        }
    }

}
</script>

控制器:

<?php


namespace App\Http\Controllers;
use JWTAuth;
use Illuminate\Support\Facades\Validator;
use Illuminate\Http\Request;
use Tymon\JWTAuth\Exceptions\JWTException;
use Illuminate\Support\Facades\Auth;
use App\Models\User;
use Symfony\Component\HttpFoundation\Response;
use Illuminate\Support\Facades\DB;
use Tymon\JWTAuth\Facades\JWTAuth as FacadesJWTAuth;
use App\Http\Requests\Users\UpdateProfileRequest;

class AuthController extends Controller

{
    public $token = true;
  
    public function __construct()
    {
        $this->middleware('auth:api', ['except' => ['login', 'register']]);
    }
    
    public function register(Request $request)
    {
 
         $validator = Validator::make($request->all(), 
                    [ 
                      'name' => 'required',
                      'email' => 'required|email',
                      'password' => 'required',  
                 
                     ]);  
 
         if ($validator->fails()) {  
               return response()->json(['error'=>$validator->errors()], 401);  
            }   
 
 
        $user = new User();
        $user->name = $request->name;
        $user->email = $request->email;
        $user->password = bcrypt($request->password);
        $user->save();
      
        if ($this->token) {
            return $this->login($request);
        }
  
        return response()->json([
            'success' => true,
            'data' => $user
        ], Response::HTTP_OK);
    }
  
    public function login(Request $request)
    {
    
        $input = $request->only('email', 'password');
        $jwt_token = null;
  
        if (!$jwt_token = JWTAuth::attempt($input)) {
            return response()->json([
                'success' => false,
                'message' => 'Invalid Email or Password',
            ], Response::HTTP_UNAUTHORIZED);
        }
  
        // return response()->json([
        //     'success' => true,
        //     'token' => $jwt_token,
        // ]);

        return $this->respondWithToken($jwt_token);
    }

    public function logout(Request $request)
    {
        $this->validate($request, [
            'token' => 'required'
        ]);
  
        try {
            JWTAuth::invalidate($request->token);
  
            return response()->json([
                'success' => true,
                'message' => 'User logged out successfully'
            ]);
        } catch (JWTException $exception) {
            return response()->json([
                'success' => false,
                'message' => 'Sorry, the user cannot be logged out'
            ], Response::HTTP_INTERNAL_SERVER_ERROR);
        }
    }

    //update user profile
    // public function updateProfile(UpdateProfileRequest $request)
    // {
    //     $user = Auth::user();
    //     $jwt_token = auth('api')->tokenById($user->id);

    //     $input = $request->all();

        
    //     if ($jwt_token) {
    //         // $user = Auth::user();
    //         // $users = $user->user;
    //         $user->name = $request->input('name', '');
    //         $user->email = $request->input('email', '');
    //         $user->save();
    //     }
    //     // $user->update($request->all());
     
    //     // return ['message' => 'Updated the user info'];
    //     return $this->respondWithToken($jwt_token);
        
    // }

    public function updateProfile(UpdateProfileRequest $request)
    {
        DB::transaction(function() use ($request){
            $user = Auth::user();
            $user->name = $request->input('name','');
            $user->email = $request->input('email','');
            $user->save();
        });

        // $user->update([
        //     'name' => $request->name,
        //     'email' => $request->email,
        // ]);
        return ['message' => 'Updated the user info sucessfully!'];
    }

    public function userProfile()
    {
        // return response()->json(auth()->user());
        $user = auth('api')->user();
        $token = auth('api')->tokenById($user->id);

        return response([
            'user' => $user,
            'token' => $token
        ]);

        // return $this->respondWithToken($token);
    }
  
    public function getUser(Request $request)
    {
        $this->validate($request, [
            'token' => 'required'
        ]);
  
        $user = JWTAuth::authenticate($request->token);
  
        return response()->json(['user' => $user]);
    }

      
    //   Refresh a token.
    public function refresh()
    {
        return $this->respondWithToken(JWTAuth::refresh());
    }

  
    // Get the token array structure
    protected function respondWithToken($token)
    {
        return response()->json([
            'access_token' => $token,
            'user' => $this->guard()->user(),
            'token_type' => 'bearer',
            'expires_in' => JWTAuth::factory()->getTTL() * 60
        ]);
    }

    public function guard() {
        return Auth::Guard('api');
    }

}
    

路线:

Route::put('/update-profile',  [AuthController::class, 'updateProfile']);

store.js

import {getLoggedinUser} from './auth';
const user = getLoggedinUser();

export default {
    state: {
        currentUser: user,
        isLoggedin: !!user,
        loading: false,
        auth_error: null,
        reg_error:null,
        registeredUser: null,
        update: null,
    },
    getters: {
        isLoading(state){
        return state.loading;
        },
        isLoggedin(state){
            return state.isLoggedin;
        },
        currentUser(state){
            return state.currentUser;
        },
        authError(state){
            return state.auth_error;    
        },
        regError(state){
            return state.reg_error;
        },
        registeredUser(state){
            return state.registeredUser;
        },
        update(state){
            return state.update;
        }
    },
    mutations: {
        login(state){
            state.loading = true;
            state.auth_error = null;
        },
        loginSuccess(state, payload){
            state.auth_error = null;
            state.isLoggedin = true;
            state.loading = false;
            state.currentUser = Object.assign({}, payload.user , {token: payload.access_token});
            localStorage.setItem("user", JSON.stringify(state.currentUser));
        },
        loginFailed(state, payload){
            state.loading = false;
            state.auth_error = payload.error;
        },
        logout(state){
            localStorage.removeItem("user");
            state.isLoggedin = false;
            state.currentUser = null;
        },
        registerSuccess(state, payload){
            state.reg_error = null;
            state.registeredUser = payload.user;
        },
        registerFailed(state, payload){
            state.reg_error = payload.error;
        },
        // update(state, payload) {
        //     state.currentUser = payload.data;      
        // }
    },
    actions: {
        login(context){
            context.commit("login");
        },
        // updateUser(context) {
        //     const token = localStorage.getItem('token')
        //     axios.put('/api/auth/update-profile', {
        //         headers: 
        //         {
        //           Authorization: `Bearer ${token}`
        //         }
        //     })
        //     .then((response) => {
        //         context.commit('update', response.data);
        //     })
        // }
    }
};

auth.js

import { setAuthorization } from "./general";

export function registerUser(credentials){
  return new Promise((res,rej)=>{
      axios.post('/api/auth/register', credentials)
      .then(response => {
          res(response.data);
      })
      .catch(err => {
          rej('An error occured.. try again later.')
      })
  })
}

export function login(credentials){
  return new Promise((res,rej)=>{
      axios.post('/api/auth/login', credentials)
      .then(response => {
            // setAuthorization(response.data.access_token);
            res(response.data);
      })
      .catch(err => {
          rej('Wrong Email/Password combination.')
      })
  })
}


export function getLoggedinUser(){
  const userStr = localStorage.getItem('user');

  if(!userStr){
      return null
  }

  return JSON.parse(userStr);
}

登录和注册功能运行良好,只是无法更新配置文件。如果您有任何解决方案或想法,请帮助我。

标签: vue.jsjwtvuexlaravel-8

解决方案


对于更新配置文件方法,承载令牌也需要传递给 axios 请求。

updateProfile () {
    const token = this.$store.getters.currentUser.token // get the token from state
    axios.put('/update-profile',
            {
                name: this.userForm.name,    
                email: this.userForm.email,
            },
            {
                headers: {
                    Authorization: `Bearer ${token}`,
                    "Content-Type": "application/json" // add content-type
                }
            })
            .then(response => {
                this.userForm.name = response.data.name;
                this.userForm.email = response.data.email; 
                swal({
                    icon: "success",
                    text: "Update Succesfully!",
                });   
            })
}

PS 如果您希望 axios 始终在所有请求中包含 Bearer 令牌而不在每个请求中指定它,您可以axios.defaults.headers,但这是另一个主题


推荐阅读