Skip to content

Instantly share code, notes, and snippets.

@eduardoarandah
Last active March 11, 2021 02:32
Show Gist options
  • Save eduardoarandah/59f93ffb74a87fda616524c57613471c to your computer and use it in GitHub Desktop.
Save eduardoarandah/59f93ffb74a87fda616524c57613471c to your computer and use it in GitHub Desktop.
Laravel Sanctum with jwt tokens in backend and vue in frontend without sessions or cors problems
import axios from "axios";
export default function () {
let api = axios.create({
baseURL: "http://localhost:8000/api",
});
let token = localStorage.getItem("token");
if (token) {
api.defaults.headers.common["Authorization"] = `Bearer ${token}`;
}
return api;
}
<?php
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Route;
use Illuminate\Validation\ValidationException;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::get("/test", function () {
return "hello from backend";
});
Route::middleware("auth:sanctum")->get("/whoami", function (Request $request) {
return $request->user();
});
Route::post("/login", function (Request $request) {
$request->validate([
"email" => "required|email",
"password" => "required",
"device_name" => "required",
]);
$user = User::where("email", $request->email)->first();
if (!$user || !Hash::check($request->password, $user->password)) {
throw ValidationException::withMessages([
"email" => "The provided credentials are incorrect.",
]);
}
return $user->createToken($request->device_name)->plainTextToken;
});
Route::post("/logout", function (Request $request) {
$request
->user()
->currentAccessToken()
->delete();
})->middleware("auth:sanctum");
"require": {
"php": "^7.3|^8.0",
"fideloper/proxy": "^4.4",
"fruitcake/laravel-cors": "^2.0",
"guzzlehttp/guzzle": "^7.0.1",
"laravel/framework": "^8.12",
+ "laravel/sanctum": "^2.9",
"laravel/tinker": "^2.5"
},
<template>
<div class="">
<input v-model="user" type="text" />
<input v-model="pass" type="password" />
<button @click="login">Login</button>
<div class="">test: <button @click="test">test</button></div>
<div class="">user: <button @click="whoami">whoami</button></div>
<div class=""><button @click="logout">Logout</button></div>
<div class="">
{{ message }}
</div>
</div>
</template>
<script>
import api from "../api/api.js";
export default {
data() {
return {
user: "[email protected]",
pass: "asdf",
message: "",
};
},
mounted: function () {},
methods: {
login: function () {
// get token
api()
.post("login", {
email: this.user,
password: this.pass,
device_name: "browser",
})
.then((r) => {
console.log(r.data);
localStorage.setItem("token", r.data);
});
},
logout: function () {
// revoke token
api()
.post("logout")
.then((r) => {
localStorage.removeItem("token");
console.log(r.data);
});
},
whoami: function () {
// test if backend auth is working
api()
.get("whoami")
.then((response) => console.log((this.message = response.data)))
.catch((error) => {
if (error.response) this.message = error.response.data.message;
throw error;
});
},
test: function () {
// this is an unauthenticated route, should always work
this.message = "";
api()
.get("test")
.then((response) => console.log((this.message = response.data)));
},
},
};
</script>
<style></style>
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
+use Laravel\Sanctum\HasApiTokens;
class User extends Authenticatable
{
use HasFactory, Notifiable;
+ use HasApiTokens;
/**
* The attributes that are mass assignable.
@eduardoarandah
Copy link
Author

Laravel base installation, with only modification to User.php and adding sanctum (don't enable sessions as documentation says)

https://laravel.com/docs/8.x/sanctum

Looks like this:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment