Warning: This article was written in 2020, the content might be out of date.
Warning: This article was written in 2020, the content might be out of date.
Categories: programming, laravel
Laravel first party package Sanctum solves the token based API implementation. Sanctum makes it very easy making your API accessible for a Single Page Application (SPA) or Token-based application.
The official documentation explains very well about how it works. The following content is how I get comfortable with Sanctum.
I started off by following the installation guide.
Then, I started to experiment with Sanctum by using Tinkerwell to get the concept.
factory(User::class)->create();
$user->createToken('test-token')->plainTextToken;
plainTextToken
to my clipboard for future use.Since I have the protected route setup. Let me test if I can access the site with the token in the terminal first.
curl http://127.0.0.1:8000/api/user \
-H "Accept: application/json" \
-H "Authorization: <plain-text-token>"
I see the JSON
representation of the user in the output. It means it is working. Then I tried with a incorrect plain-text-token
, it shows {"message", "unauthenticated"}
. The token based system is working. π
Now, letβs try this in PHP.
$client = new GuzzleHttp\Client([
]);
$headers = [
'Authorization' => 'Bearer '.$plainTextToken,
'Accept' => 'application/json'
];
$response = $client->get('https://127.0.0.1:8000/api/user', [
'headers' => $headers
]);
It works because I can again see the json
representation of the user. API token based works.
Next, I work on the SPA authentication.
There are couple things needs to be taken care of.
Thankfully, there is a package call fruitcake/laravel-cors that helps easing the CORS settings.
// Update config/cors.php to allow CORS
'paths' => ['api/*', 'sanctum/*']
'supports_credentials' => true,
// Update stateful in
// config/sanctum.php or .env
// if your URL has specific port, you must include it.
'stateful' => explode(',', 'your-spa-domain:3000');
Then, I build a Vue application to test authenticating through a SPA. I use axios to handle the background fetch.
import axios from "axios";
// enable withCredentials
// `withCredentials` indicates whether or not cross-site Access-Control
// requests should be made using credentials
axios.defaults.withCredentials = true;
Then I created a button, a form with email and password in a single file component (SFC). The important line is getting the CSRF cookie to allow authentication with Laravel Sanctum.
// create a login function
login() {
axios.get("//localhost:8000/sanctum/csrf-cookie/").then(
(response) => {
axios
.post("//127.0.0.1:8000/login", {
email: this.email,
password: this.password,
})
.then(
(response) => {
// handle response
},
function (error) {
// handle error
}
);
},
function (error) {
console.log(error.response.statusText);
}
);
}
Next, I created a method as a test to retrieve a protected route to see if I can get the protected data.
getProtectedContent: {
axios
.get("//127.0.0.1:8000/api/api-user")
.then((response) => console.log(response.data));
}
I also created a logout button, just to clear out the session and see if I still could get the data from a protected route.
logout() {
axios.post("//127.0.0.1:8000/logout");
}
It works.
Laravel Sanctum made creating a token based API or SPA authentication very easy to implement. Laravel just made another developer experience very happy. π