Laravel JWT Auth with Vue.js 2 - Page 2
Vue Resource
In order to post the Registration form data, the Vue.js resource plugin needs to be installed.
npm i vue-resource --save-dev
Update resources/js/app.js to import the vue-resource plugin after the vue-router.
Add the Vue.use
statement for the vue-resource
.
Add the Vue.http.headers
and Vue.http.options.root
url.
Laravel VerifyCsrfToken
middleware will check for the X-CSRF-TOKEN request header. To make this token available to the client side script, it is being stored in the csrf-token
meta tag near the top of the web page. The Authorization header is needed for JWT auth which will be added with the sign-in form later.
app.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import VueResource from 'vue-resource';
...
Vue.use(VueRouter);
Vue.use(VueResource);
Vue.http.headers.common['X-CSRF-TOKEN'] = document.getElementsByName('csrf-token')[0].getAttribute('content');
Vue.http.headers.common['Authorization'] = 'Bearer ' + localStorage.getItem('id_token');
Vue.http.options.root = 'http://laravel.dev:8080';
...
Create a resources/js/auth.js JavaScript file.
touch assets/js/auth.js
Add code to auth.js to set the default user and register form handler.
auth.js
import Vue from './app.js';
import {router} from './app.js';
export default {
user: {
authenticated: false,
profile: null
},
register(context, name, email, password) {
Vue.http.post(
'api/register',
{
name: name,
email: email,
password: password
}
).then(response => {
context.success = true
}, response => {
context.response = response.data
context.error = true
})
}
}
Add a script to the bottom of the Register.vue
file for the default data and register form handler.
Register.vue
...
</template>
<script>
import auth from '../js/auth.js';
export default {
data() {
return {
name: null,
email: null,
password: null,
success: false,
error: false,
response: null
}
},
methods: {
register(event) {
event.preventDefault()
auth.register(this, this.name, this.email, this.password)
}
}
}
</script>
API
For form validation, generate a FormRequest class using artisan.
php artisan make:request RegisterFormRequest
Edit app/Http/Requests/RegisterFormRequest.php. First, return true instead of false in the authorize function since using JWT for that. Then add the validation rules in the array that is returned in the rules function for the new User.
RegisterFormRequest.php
public function authorize()
{
return true;
}
...
public function rules()
{
return [
'name' => 'required',
'email' => 'required|email|unique:users',
'password' => 'required',
];
}
Edit the pre-existing app/Http/Controllers/Auth/AuthController.php. Replace everything below the namespace declaration with this code.
AuthController.php
...
use App\Models\User;
use App\Http\Controllers\Controller;
use App\Http\Requests\RegisterFormRequest;
use Illuminate\Http\Request;
class AuthController extends Controller
{
public function register(RegisterFormRequest $request)
{
User::create([
'name' => $request->json('name'),
'email' => $request->json('email'),
'password' => bcrypt($request->json('password')),
]);
}
}
Test the form and API by registering a new user. Check the users table in the database for a new row for the user that was just added. Try registering another new user with the same e-mail address to test the validation.
JWT Auth
For Laravel JSON web token authentication, install jwt-auth using composer require.
composer require tymon/jwt-auth
Edit config\app.php adding the service JWTAuthServiceProvider to the providers array and under the aliases array, add the JWTAuth facade.
app.php
...
'providers' => [
...
Tymon\JWTAuth\Providers\JWTAuthServiceProvider::class,
]
...
'aliases' => [
...
'JWTAuth' => Tymon\JWTAuth\Facades\JWTAuth::class,
]
Publish the configuration.
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\JWTAuthServiceProvider"
Generate a key in the published configuration.
php artisan jwt:generate
Edit the published configration config\jwt.php file by updating 'user' => 'App\User'
since the User model namespace has been changed from the default.
jwt.php
...
'user' => App\Models\User::class,
User Endpoint
Create the User controller.
php artisan make:controller UserController
Edit the app\Http\Controllers\UserController.php adding the index method to return the user data.
UserController.php
...
use Illuminate\Http\Request;
use App\Http\Requests;
class UserController extends Controller
{
public function index(Request $request)
{
$data = [];
$data['name'] = $request->user()->name;
$data['email'] = $request->user()->email;
return response()->json([
'data' => $data,
]);
}
}
Add the signin method to the AuthController
class and update the use statements for the external classes.
AuthController.php
...
use App\Models\User;
use App\Http\Controllers\Controller;
use App\Http\Requests\RegisterFormRequest;
use Carbon\Carbon;
use JWTAuth;
use Illuminate\Http\Request;
use Tymon\JWTAuth\Exceptions\JWTException;
class AuthController extends Controller
{
public function register(RegisterFormRequest $request)
{
User::create([
'name' => $request->json('name'),
'email' => $request->json('email'),
'password' => bcrypt($request->json('password')),
]);
}
public function signin(Request $request)
{
try {
$token = JWTAuth::attempt($request->only('email', 'password'), [
'exp' => Carbon::now()->addWeek()->timestamp,
]);
} catch (JWTException $e) {
return response()->json([
'error' => 'Could not authenticate',
], 500);
}
if (!$token) {
return response()->json([
'error' => 'Could not authenticate',
], 401);
} else {
$data = [];
$meta = [];
$data['name'] = $request->user()->name;
$meta['token'] = $token;
return response()->json([
'data' => $data,
'meta' => $meta
]);
}
}
}
Edit app\Http\Kernel.php adding jwt.auth
to the application’s route middleware array.
kernel.php
...
protected $routeMiddleware = [
...
'jwt.auth' => \Tymon\JWTAuth\Middleware\GetUserFromToken::class,
];
Edit app\Http\routes.php - at the bottom of the file, add the signin and jwt.auth
route group to authorize access to the user endpoint.
routes.php
...
Route::group(['middleware' => ['api']], function () {
Route::post('/api/register', [
'uses' => 'Auth\AuthController@register',
]);
Route::post('/api/signin', [
'uses' => 'Auth\AuthController@signin',
]);
Route::group(['middleware' => 'jwt.auth'], function () {
Route::get('/user', [
'uses' => 'UserController@index',
]);
});
});
The last page covers the rest of the front end code including sign in, sign out and navigation updates.