{"id":50310,"date":"2025-07-15T21:52:24","date_gmt":"2025-07-15T21:52:24","guid":{"rendered":"https:\/\/www.devopsschool.com\/blog\/?p=50310"},"modified":"2026-02-21T07:36:27","modified_gmt":"2026-02-21T07:36:27","slug":"laravel-complete-guide-of-laravel-passport","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/blog\/laravel-complete-guide-of-laravel-passport\/","title":{"rendered":"Laravel: Complete Guide of Laravel Passport"},"content":{"rendered":"\n<p>Here\u2019s a <strong>comprehensive, up-to-date step-by-step tutorial for setting up and using Laravel Passport<\/strong> (OAuth2 API authentication) with clear explanations, working code samples, and <strong>troubleshooting tips<\/strong>\u2014suitable for local XAMPP and production environments.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h1 class=\"wp-block-heading\">Laravel Passport Full Tutorial (2026)<\/h1>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h2 class=\"wp-block-heading\">1. <strong>What is Laravel Passport?<\/strong><\/h2>\n\n\n\n<p><strong>Laravel Passport<\/strong> provides a full OAuth2 server implementation for your Laravel application in minutes.<br>It&#8217;s used when you want to secure your API endpoints (e.g., for microservices or mobile\/web clients) with OAuth2\u2014supporting access tokens, refresh tokens, personal access, and password grants.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h2 class=\"wp-block-heading\">2. <strong>Requirements<\/strong><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Laravel 10 or 11+<\/li>\n\n\n\n<li>PHP 8.1+<\/li>\n\n\n\n<li>Composer<\/li>\n\n\n\n<li>MySQL\/SQLite (or any supported DB)<\/li>\n\n\n\n<li><strong>mod_rewrite enabled<\/strong> on Apache (XAMPP)<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h2 class=\"wp-block-heading\">3. <strong>Installation Steps<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">a. <strong>Install Passport<\/strong><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">composer <span class=\"hljs-built_in\">require<\/span> laravel\/passport\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">b. <strong>Run Passport Install<\/strong><\/h3>\n\n\n\n<p>This will generate encryption keys, migration files, and optional clients.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">php<\/span> <span class=\"hljs-selector-tag\">artisan<\/span> <span class=\"hljs-selector-tag\">passport<\/span><span class=\"hljs-selector-pseudo\">:install<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>If prompted, let it run migrations.<br>If you skip, run <code>php artisan migrate<\/code> manually.<\/p>\n<\/blockquote>\n\n\n\n<p><strong>Common Issues:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>If you see \u201cencryption keys already exist,\u201d use <code>--force<\/code>.<\/li>\n\n\n\n<li>If tables already exist, clear your DB or delete <code>oauth_*<\/code> tables and re-migrate.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">c. <strong>Publish Config (optional)<\/strong><\/h3>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">php artisan vendor:publish --tag=passport-config\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h2 class=\"wp-block-heading\">4. <strong>Configure Laravel<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">a. <strong>Service Provider<\/strong><\/h3>\n\n\n\n<p>If using Laravel 10+, this is automatic.<br>If not, add in <code>config\/app.php<\/code> under <code>providers<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">LaravelPassportPassportServiceProvider::<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span>,\n<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">b. <strong>Database Migrations<\/strong><\/h3>\n\n\n\n<p>Run if not done already:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">php artisan migrate\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h2 class=\"wp-block-heading\">5. <strong>Set Up Auth in Laravel<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">a. <strong>In <code>app\/Models\/User.php<\/code><\/strong><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">LaravelPassportHasApiTokens<\/span>;\n\n<span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">User<\/span> <span class=\"hljs-keyword\">extends<\/span> <span class=\"hljs-title\">Authenticatable<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">HasApiTokens<\/span>, <span class=\"hljs-title\">Notifiable<\/span>;\n    <span class=\"hljs-comment\">\/\/...<\/span>\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">b. <strong>In <code>config\/auth.php<\/code><\/strong><\/h3>\n\n\n\n<p>Set <code>api<\/code> driver to <code>passport<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-string\">'guards'<\/span> =&gt; &#91;\n    <span class=\"hljs-string\">'api'<\/span> =&gt; &#91;\n        <span class=\"hljs-string\">'driver'<\/span> =&gt; <span class=\"hljs-string\">'passport'<\/span>,\n        <span class=\"hljs-string\">'provider'<\/span> =&gt; <span class=\"hljs-string\">'users'<\/span>,\n    ],\n],\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">c. <strong>In <code>app\/Providers\/AuthServiceProvider.php<\/code><\/strong><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">use<\/span> <span class=\"hljs-title\">LaravelPassportPassport<\/span>;\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">boot<\/span><span class=\"hljs-params\">()<\/span>\n<\/span>{\n    <span class=\"hljs-keyword\">$this<\/span>-&gt;registerPolicies();\n\n    Passport::routes(); <span class=\"hljs-comment\">\/\/ Enables Passport routes<\/span>\n    <span class=\"hljs-comment\">\/\/ Optionally, set token expiration here<\/span>\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h2 class=\"wp-block-heading\">6. <strong>Create OAuth Clients<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">a. <strong>Client Credentials Grant (machine-to-machine, microservices):<\/strong><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">php<\/span> <span class=\"hljs-selector-tag\">artisan<\/span> <span class=\"hljs-selector-tag\">passport<\/span><span class=\"hljs-selector-pseudo\">:client<\/span> <span class=\"hljs-selector-tag\">--client<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<ul class=\"wp-block-list\">\n<li>Note the <code>Client ID<\/code> and <code>Client Secret<\/code>\u2014you need them for token requests.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">b. <strong>Password Grant (for username\/password login):<\/strong><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">php<\/span> <span class=\"hljs-selector-tag\">artisan<\/span> <span class=\"hljs-selector-tag\">passport<\/span><span class=\"hljs-selector-pseudo\">:client<\/span> <span class=\"hljs-selector-tag\">--password<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">c. <strong>Personal Access Client (for tokens not attached to users):<\/strong><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">php<\/span> <span class=\"hljs-selector-tag\">artisan<\/span> <span class=\"hljs-selector-tag\">passport<\/span><span class=\"hljs-selector-pseudo\">:client<\/span> <span class=\"hljs-selector-tag\">--personal<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h2 class=\"wp-block-heading\">7. <strong>Protect Your Routes<\/strong><\/h2>\n\n\n\n<p>In <code>routes\/api.php<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">Route::middleware(<span class=\"hljs-string\">'auth:api'<\/span>)-&gt;get(<span class=\"hljs-string\">'\/user'<\/span>, <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-params\">(Request $request)<\/span> <\/span>{\n    <span class=\"hljs-keyword\">return<\/span> $request-&gt;user();\n});\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Or for controller routes:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">Route<\/span><span class=\"hljs-selector-pseudo\">::middleware('auth<\/span><span class=\"hljs-selector-pseudo\">:api')-<\/span>&gt;<span class=\"hljs-selector-tag\">group<\/span>(<span class=\"hljs-selector-tag\">function<\/span> () {\n    <span class=\"hljs-attribute\">Route<\/span>::<span class=\"hljs-built_in\">get<\/span>(<span class=\"hljs-string\">'\/orders'<\/span>, &#91;OrderController::class, <span class=\"hljs-string\">'index'<\/span>]);\n});\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h2 class=\"wp-block-heading\">8. <strong>How to Get a Token (Machine-to-Machine, Client Credentials Grant)<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">a. <strong>cURL Command:<\/strong><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">curl -X POST <span class=\"hljs-string\">\"http:\/\/localhost\/yourproject\/oauth\/token\"<\/span> \n  -H <span class=\"hljs-string\">\"Content-Type: application\/x-www-form-urlencoded\"<\/span> \n  -d <span class=\"hljs-string\">\"grant_type=client_credentials&amp;client_id=YOUR_CLIENT_ID&amp;client_secret=YOUR_CLIENT_SECRET\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><strong>If using JSON:<\/strong><\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">curl -X POST <span class=\"hljs-string\">\"http:\/\/localhost\/yourproject\/oauth\/token\"<\/span> \n  -H <span class=\"hljs-string\">\"Content-Type: application\/json\"<\/span> \n  -d <span class=\"hljs-string\">'{\"grant_type\":\"client_credentials\",\"client_id\":\"YOUR_CLIENT_ID\",\"client_secret\":\"YOUR_CLIENT_SECRET\"}'<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">b. <strong>Example Response:<\/strong><\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"JSON \/ JSON with Comments\" data-shcb-language-slug=\"json\"><span><code class=\"hljs language-json\">{\n    <span class=\"hljs-attr\">\"token_type\"<\/span>: <span class=\"hljs-string\">\"Bearer\"<\/span>,\n    <span class=\"hljs-attr\">\"expires_in\"<\/span>: <span class=\"hljs-number\">31536000<\/span>,\n    <span class=\"hljs-attr\">\"access_token\"<\/span>: <span class=\"hljs-string\">\"eyJ0eXA...\"<\/span>\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JSON \/ JSON with Comments<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">json<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h2 class=\"wp-block-heading\">9. <strong>Use the Token in API Requests<\/strong><\/h2>\n\n\n\n<p>Add as a Bearer token in your header:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">curl -H <span class=\"hljs-string\">\"Authorization: Bearer ACCESS_TOKEN_HERE\"<\/span> http:<span class=\"hljs-comment\">\/\/localhost\/yourproject\/api\/user<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Or with Guzzle in Laravel:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">$response = Http::withToken($accessToken)-&gt;get(<span class=\"hljs-string\">'http:\/\/localhost\/yourproject\/api\/user'<\/span>);\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h2 class=\"wp-block-heading\">10. <strong>Troubleshooting<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">a. <strong>404 on <code>\/oauth\/token<\/code><\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Make sure you\u2019re calling the <em>public<\/em> entry (e.g., <code>\/yourproject\/oauth\/token<\/code>).<\/li>\n\n\n\n<li>Ensure <code>.htaccess<\/code> is standard and mod_rewrite is enabled.<\/li>\n\n\n\n<li>Check Alias in Apache vhost (should point <code>\/yourproject<\/code> to <code>public<\/code> folder).<\/li>\n\n\n\n<li>Run <code>php artisan route:list | grep oauth<\/code> to confirm the route exists.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">b. <strong>405 Method Not Allowed<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>You\u2019re likely using the wrong HTTP verb (must be POST for <code>\/oauth\/token<\/code>).<\/li>\n\n\n\n<li>Try hitting <code>\/yourproject\/index.php\/oauth\/token<\/code> to bypass .htaccess (diagnostic).<\/li>\n\n\n\n<li>If this works, .htaccess or mod_rewrite is not working.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">c. <strong>403 Forbidden<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Check <code>.htaccess<\/code> for PHP file restrictions.<\/li>\n\n\n\n<li>Ensure <code>AllowOverride All<\/code> is set in Apache config for your Directory.<\/li>\n\n\n\n<li>Check permissions of the <code>public<\/code> folder.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">d. <strong>Token not working<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Confirm your API route uses <code>auth:api<\/code> middleware.<\/li>\n\n\n\n<li>Confirm correct guard in <code>config\/auth.php<\/code>.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h2 class=\"wp-block-heading\">11. <strong>Environment Variables Best Practices<\/strong><\/h2>\n\n\n\n<p><strong>Separate internal and public URLs:<\/strong><br>Add these in your <code>.env<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">APP_URL=https:<span class=\"hljs-comment\">\/\/www.myhospitalnow.com\/yourproject<\/span>\nINTERNAL_API_URL=http:<span class=\"hljs-comment\">\/\/localhost\/yourproject<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p><strong>In code:<\/strong><\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">$apiBase = env(<span class=\"hljs-string\">'INTERNAL_API_URL'<\/span>, config(<span class=\"hljs-string\">'app.url'<\/span>));\n$response = Http::post(<span class=\"hljs-string\">\"$apiBase\/oauth\/token\"<\/span>, &#91;...]);\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h2 class=\"wp-block-heading\">12. <strong>Testing Everything<\/strong><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>curl -I http:\/\/localhost\/yourproject\/<\/code> (should return 200 OK)<\/li>\n\n\n\n<li><code>curl -X POST ...\/oauth\/token<\/code> (should return access token)<\/li>\n\n\n\n<li><code>curl -H \"Authorization: Bearer ...\" ...\/api\/user<\/code> (should return user info)<\/li>\n\n\n\n<li><code>php artisan route:list | grep oauth<\/code> (should show token route)<\/li>\n\n\n\n<li>Check your logs for errors.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h2 class=\"wp-block-heading\">13. <strong>Production Tips<\/strong><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use HTTPS for public endpoints.<\/li>\n\n\n\n<li>Never expose your <code>.env<\/code> or sensitive client secrets.<\/li>\n\n\n\n<li>Restrict token scopes to only what&#8217;s necessary.<\/li>\n\n\n\n<li>Rotate client secrets if leaked.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h2 class=\"wp-block-heading\">14. <strong>References<\/strong><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/laravel.com\/docs\/11.x\/passport\" target=\"_blank\" rel=\"noopener\">Laravel Passport Docs<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/oauth.net\/2\/\" target=\"_blank\" rel=\"noopener\">OAuth2 Overview<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/github.com\/laravel\/passport\" target=\"_blank\" rel=\"noopener\">Official Laravel Example<\/a><\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<p><strong>Want to see a Dockerized version, multi-service microservices setup, or real-world client integration code? Just ask!<\/strong><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<p>Let me know if you want a <strong>production deployment checklist<\/strong>, more about securing microservices, or a walkthrough for specific grant types (password, auth code, etc.).<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Laravel Passport on XAMPP: Debug Checklist<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Routes Confirmed<\/h2>\n\n\n\n<p>You ran <code>php artisan route:list<\/code> and see:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>POST oauth\/token &#8230; passport.token<\/li>\n\n\n\n<li>(etc)<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Problem<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>curl -I http:\/\/localhost\/rajesh\/<\/code> returns 200 OK.<\/li>\n\n\n\n<li><code>curl -X POST http:\/\/localhost\/rajesh\/oauth\/token ...<\/code> returns 404 Not Found.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Next Steps<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Check .htaccess<\/strong> in <code>\/opt\/lampp\/htdocs\/myhospitalnow\/rajesh\/public<\/code>:\n<ul class=\"wp-block-list\">\n<li>Should be standard Laravel version (see below).<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Check Apache Alias &amp; Directory<\/strong><ul><li>In your httpd-vhosts.conf or httpd.conf, you should have:<\/li><\/ul><code>Alias \/rajesh \/opt\/lampp\/htdocs\/myhospitalnow\/rajesh\/public &lt;Directory \/opt\/lampp\/htdocs\/myhospitalnow\/rajesh\/public&gt; Options Indexes FollowSymLinks AllowOverride All Require all granted &lt;\/Directory&gt;<\/code>\n<ul class=\"wp-block-list\">\n<li>After editing, restart Apache.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Test Index.php Direct Access<\/strong><ul><li>Run:<\/li><\/ul><code>curl -X POST http:\/\/localhost\/rajesh\/index.php\/oauth\/token ...<\/code>\n<ul class=\"wp-block-list\">\n<li>If this works: <code>.htaccess<\/code> or mod_rewrite is not working.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Check mod_rewrite is enabled<\/strong><ul><li>Run:<\/li><\/ul><code>apachectl -M | grep rewrite<\/code>\n<ul class=\"wp-block-list\">\n<li>Should show <code>rewrite_module<\/code>.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Check Directory Index<\/strong>\n<ul class=\"wp-block-list\">\n<li>Make sure your <code>\/opt\/lampp\/htdocs\/myhospitalnow\/rajesh\/public<\/code> has <code>index.php<\/code> present and readable.<\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>Check File Permissions<\/strong>\n<ul class=\"wp-block-list\">\n<li>Run <code>ls -al \/opt\/lampp\/htdocs\/myhospitalnow\/rajesh\/public<\/code><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><strong>If still stuck<\/strong>\n<ul class=\"wp-block-list\">\n<li>Post your <code>\/opt\/lampp\/htdocs\/myhospitalnow\/rajesh\/public\/.htaccess<\/code><\/li>\n\n\n\n<li>Post your relevant Apache vhost\/alias config.<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\">\n\n\n\n<h2 class=\"wp-block-heading\">Sample .htaccess<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-19\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">IfModule<\/span> <span class=\"hljs-attr\">mod_rewrite.c<\/span>&gt;<\/span>\n    RewriteEngine On\n    RewriteCond %{REQUEST_FILENAME} !-d\n    RewriteCond %{REQUEST_FILENAME} !-f\n    RewriteRule ^ index.php &#91;L]\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">IfModule<\/span>&gt;<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-19\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">Command<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-20\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-number\">2099<\/span>  composer create-project laravel\/laravel rajesh\n <span class=\"hljs-number\">2100<\/span>  cd rajesh\/\n <span class=\"hljs-number\">2103<\/span>  composer <span class=\"hljs-keyword\">require<\/span> laravel\/passport\n <span class=\"hljs-number\">2104<\/span>  php artisan passport:install\n <span class=\"hljs-number\">2107<\/span>  php artisan migrate\n <span class=\"hljs-number\">2108<\/span>  php artisan passport:client\n <span class=\"hljs-number\">2112<\/span>  php artisan route:<span class=\"hljs-keyword\">list<\/span> | grep oauth\n <span class=\"hljs-number\">2113<\/span>  vi \/opt\/lampp\/etc\/extra\/httpd-localhost.conf\n <span class=\"hljs-number\">2114<\/span>  \/opt\/lampp\/lampp restart\n <span class=\"hljs-number\">2115<\/span>  php artisan route:<span class=\"hljs-keyword\">list<\/span> | grep oauth\n <span class=\"hljs-number\">2119<\/span>  curl -I http:<span class=\"hljs-comment\">\/\/localhost\/rajesh\/<\/span>\n <span class=\"hljs-number\">2120<\/span>  php artisan route:<span class=\"hljs-keyword\">list<\/span>\n <span class=\"hljs-number\">2121<\/span>  ls <span class=\"hljs-keyword\">public<\/span>\/.htaccess\n <span class=\"hljs-number\">2122<\/span>  more <span class=\"hljs-keyword\">public<\/span>\/.htaccess\n <span class=\"hljs-number\">2123<\/span>  vi \/opt\/lampp\/etc\/extra\/httpd-localhost.conf\n <span class=\"hljs-number\">2125<\/span>  \/opt\/lampp\/lampp restart\n <span class=\"hljs-number\">2126<\/span>  curl -X POST <span class=\"hljs-string\">\"http:\/\/localhost\/rajesh\/oauth\/token\"<\/span>   -H <span class=\"hljs-string\">\"Content-Type: application\/x-www-form-urlencoded\"<\/span>   -d <span class=\"hljs-string\">\"grant_type=client_credentials&amp;client_id=01981006-d7bd-72ad-b931-39a792643c83&amp;client_secret=6q3yC4cCttUi28mAX6ITFocvOpkhyyWyKzX4eQVw\"<\/span>\n <span class=\"hljs-number\">2127<\/span>  history<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-20\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>","protected":false},"excerpt":{"rendered":"<p>Here\u2019s a comprehensive, up-to-date step-by-step tutorial for setting up and using Laravel Passport (OAuth2 API authentication) with clear explanations, working code samples, and troubleshooting tips\u2014suitable for local XAMPP and production&#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"_joinchat":[],"footnotes":""},"categories":[2],"tags":[],"class_list":["post-50310","post","type-post","status-publish","format-standard","hentry","category-uncategorised"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/50310","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/comments?post=50310"}],"version-history":[{"count":3,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/50310\/revisions"}],"predecessor-version":[{"id":59138,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/50310\/revisions\/59138"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media?parent=50310"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/categories?post=50310"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/tags?post=50310"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}