I have created ApiController in App\Http\Controllers\Api\v1
Also created auth using laravel/ui
Default created function for front end working perfectly.
But issue is when try to call the ApiController
My API Route file is as below
Route::group(['prefix' => 'api/v1', 'namespace' => 'Api\v1'], function () {
Route::post('register', 'ApiController#register');
});
And my API controller look like
namespace App\Http\Controllers\Api\v1;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class ApiController extends Controller
{
public function register(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
'api_token' => Str::random(60),
]);
}
}
Before 404 it was csrf error and i have resolving it by
protected $except = [
'/register',
];
in Http\Middleware\VerifyCsrfToken
I cant figure out two question
How to except my entire api call from CSRF using $except..
How to solve 404 for register method , i use postman with POST request and call URL http://localhost/larablog/api/v1/register
Routes defined in the routes/api.php file are nested within a route group by the RouteServiceProvider. Within this group, the /api URI prefix is automatically applied so you do not need to manually apply it to every route in the file. You may modify the prefix and other route group options by modifying your RouteServiceProvider class.
1) 404 error :- Remove api from prefix route.
Route::group(['prefix' => 'v1', 'namespace' => 'Api\v1'], function () {
Route::post('register', 'ApiController#register');
});
http://localhost/larablog/api/v1/register
1. If you are using a route group:
Route::group(['prefix' => 'v1', 'namespace' => 'Api\v1'], function () {
Route::post('register', 'ApiController#register');
});
Your $except array looks like:
protected $except = ['v1/register'];
2. If you want to exclude all routes under v1
Your $except array looks like:
protected $except = ['v1/*'];
Related
iam new in laravel , and i wrote this code at routes/api.php in laravel 9
Route::group([
'prefix' => 'auth',
'namespace' => 'Auth'
], function(){
Route::post('register', 'RegisterController');
});
and then i got cant run php artisan serve , it said
UnexpectedValueException
Invalid route action: [Auth\RegisterController].
at G:\PRODUCTIVITY\SANBERCODE\LARAVEL-VUE\TUGAS\laravel-vue-crowdfunding-website-batch-37\crowdfunding-website\vendor\laravel\framework\src\Illuminate\Routing\RouteAction.php:92
88▕ */
89▕ protected static function makeInvokable($action)
90▕ {
91▕ if (! method_exists($action, '__invoke')) {
➜ 92▕ throw new UnexpectedValueException("Invalid route action: [{$action}].");
93▕ }
94▕
95▕ return $action.'#__invoke';
96▕ }
1 G:\PRODUCTIVITY\SANBERCODE\LARAVEL-VUE\TUGAS\laravel-vue-crowdfunding-website-batch-37\crowdfunding-website\vendor\laravel\framework\src\Illuminate\Routing\RouteAction.php:47
Illuminate\Routing\RouteAction::makeInvokable("Auth\RegisterController")
2 G:\PRODUCTIVITY\SANBERCODE\LARAVEL-VUE\TUGAS\laravel-vue-crowdfunding-website-batch-37\crowdfunding-website\vendor\laravel\framework\src\Illuminate\Routing\Route.php:190
Illuminate\Routing\RouteAction::parse("api/auth/register", ["Auth\RegisterController", "Auth\RegisterController"])
someone please help me :)
Add RegisterController function
Route::group([
'prefix' => 'auth',
'namespace' => 'Auth'
], function(){
Route::post('register', 'RegisterController#store');
});
You are missing a parameter in your post function from Route.
You want something like
Route::post('route_name', 'Controller#myFunction')
Or in your case:
Route::post('register', 'RegisterController#registerFunctionName');
Other variation per 9.x documentation:
Route::post('register', [RegisterController::class, 'registerFunctionName']);
Please refer to:
https://laravel.com/docs/9.x/routing
This is an invokable controller yes?
you need to just alter the syntax
Route::group([
'prefix' => 'auth',
'namespace' => 'Auth'
], function(){
Route::post('register', [RegisterController::class]);
});
and then import the class at the top of your routes file and make sure you have a single public method of __invoke() in your controller.
I've run into a problem with the updated version of Laravel and the new routing.
The route with the resources works just fine and uses the correct namespace, the problem is with the direct route "users/table", it's not using any namespace and returns "Target class [UserController] does not exist."
.
When I apply the full controller namespace and class name it works. I've modified my RouteResourceProvider.php and it's loading the default namespace on boot.
My question is why the resources method works but for the custom route, I have to specify the entire namespace inside the route group with an already set namespace?
Route::group(['prefix' => 'admin', 'as' => 'admin.', 'namespace' => 'Admin'], function () {
Route::post('users/table', [UserController::class, 'table']);
...
Route::resources([
'users' => UserController::class,
...
]);
});
Route::group(['prefix' => 'admin', 'as' => 'admin.', 'namespace' => 'App\Http\Controllers\Admin'], function () {
Route::post('users/table', [UserController::class, 'table']);
...
Route::resources([
'users' => UserController::class,
...
]);});
For a purpose i decided to create a separate routing file for the admin and separating its logic from the web.php but instead i am facing this issue :
//admin.php ( routing file )
<?php
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Auth
Route::get('/admin', function ()
{
dd(Auth::user()); //return null
});
ps: the admin.php is registered in the RouteServiceProvider
public function map()
{
$this->mapApiRoutes();
$this->mapWebRoutes();
$this->mapAdminRoutes();
//
}
protected function mapAdminRoutes()
{
Route::middleware('admin')
->namespace('App\Http\Controllers\Admin')
->group(base_path('routes/admin.php'));
}
Add web middleware
Route::middleware(['web','admin'])->...
Let's try to defining the new route in config/auth.php
'guards' => [
'admin' => [
'driver' => 'session',
'provider' => 'users',
]
],
because you want to get session to check Auth.
So let try this one.
I am setting like and unlike options on articles. but in LikeController there is problem. when I push the like button it says ->
SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'user_id'
cannot be null (SQL: insert into likes (user_id, article_id,
updated_at, created_at) values (?, 5, 2019-05-30 07:58:34,
2019-05-30 07:58:34))
Updated JWT and Routes
Like model:
class Like extends Model
{
public $timestamps = true;
public $with = ["user"];
protected $fillable = ["user_id", "article_id"];
public function article()
{
return $this->belongsTo("App\Article");
}
public function user()
{
return $this->belongsTo("App\User");
}
}
and LikeController:
use Auth;
use App\Article;
use App\Like;
public function like($id)
{
$article = Article::find($id);
$like = Like::create([
"user_id" => Auth::id(),
"article_id" => $article->id
]);
return Like::find($like->id);
}
public function unlike($id)
{
$article = Article::find($id);
Like::where("user_id", Auth::id())
->where("article_id", $article->id)
->first()
->delete();
return 1;
}
I am not very sure why Auth::id() can't find the user id and return null?
Using JWT with vue.js
Routes:
Route::group(['prefix' => 'auth'], function ($router) {
Route::post('register', 'AuthController#register');
Route::post('login', 'AuthController#login');
Route::post('logout', 'AuthController#logout');
Route::post('refresh', 'AuthController#refresh');
Route::post('me', 'AuthController#me');
});
Route::get("/like/{id}", [
"uses" => "LikeController#like"
]);
Route::get("/unlike/{id}", [
"uses" => "LikeController#unlike"
]);
AuthController and User
to set controller and user model I followed the docs: https://jwt-auth.readthedocs.io/en/develop/quick-start/
You seem to have not protected your LikeController routes with auth.
Unless you have something like this in your LikeController for constructor:
public function __construct()
{
$this->middleware('auth:api');
}
then you should have your LikeController routes protected like this:
Route::group([
'middleware' => 'api',
], function ($router) {
Route::get("/like/{id}", [
"uses" => "LikeController#like"
]);
Route::get("/unlike/{id}", [
"uses" => "LikeController#unlike"
]);
});
Then the correct way of getting the logged in used is
auth('api')->user()
or
Auth::guard('api')->user()
Auth::user()->id
use this code
Try importing Auth as such
use Illuminate\Support\Facades\Auth;
and getting the ID like this:
$user = Auth::user();
$id = $user->id;
Hope this helps
Add this middelware on kernel.php
protected $middlewareGroups = [
'web' => [
\Illuminate\Session\Middleware\StartSession::class,
],
];
this link might help :
Answer Link
first: ensure that route or Controller protected by auth middleware.
second: ensure that you are using correct guard for auth, if using multiple guard.
you should specify your guard name like this: `Auth::guard('admin')->id()`
You have missed to specify the middleware => api from the route groups. Also include the like related routes Or any protected routes within this routegroup.
config/auth.php shoud be updated as
'defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
...
'guards' => [
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
],
In routes/api.php
Route::post('login', 'AuthController#login')->name('login');
Route::group(['middleware' => 'api'], function ($router) {
Route::group(['prefix' => 'auth'], function ($router) {
Route::post('register', 'AuthController#register');
# Route::post('login', 'AuthController#login'); // commented.
Route::post('logout', 'AuthController#logout');
Route::post('refresh', 'AuthController#refresh');
Route::post('me', 'AuthController#me');
});
Route::get("/like/{id}", [
"uses" => "LikeController#like"
]);
Route::get("/unlike/{id}", [
"uses" => "LikeController#unlike"
]);
});
Ok ,
so i was also having that issue with my app when i was using jwt with vue js.
for getting current Auth::user().
You need to pass token with your request.
if you check jwt core file, It getting user from token.
and you are not passing token I guess.
If yes then please pass token along with your request.
And also check the documentation of jwt. did you install your package properly?
remember for laravel 5.5 or greater, that package version to use is jwt > 1.0.0
also, check the documentation of that version properly.
Also you can use passport from Laravel where you have OAuth2 :-)
Laravel Documentation about Laravel Passport say:
Laravel makes API authentication a breeze using Laravel Passport,
which provides a full OAuth2 server implementation for your Laravel
application in a matter of minutes. Passport is built on top of the
League OAuth2 server that is maintained by Andy Millington and Simon
Hamp.
You can look more information here where you see Laravel Passport Documentation
Check if User is authenticated or not,
and don't forgot to use Auth class.
use Auth;
check if auth than delete,
And Use Auth::user()->id
if (Auth::user())
{
Like::where("user_id", Auth::user()->id)
->where("article_id", $article->id)
->first()
->delete();
}
When trying to go to an auth required middleware page I'm getting 'Route [login] not defined' the problem is, my login route isn't called 'login' and I don't want it to be called login.
Here are my routes...
Route::group(['middleware' => 'auth', 'namespace' => 'User'], function() {
Route::get('/home', ['uses' => 'HomeController#getView', 'as' => 'frontend.user.home']);
});
Route::group(['middleware' => 'guest', 'namespace' => 'Guest'], function() {
Route::get('/login', ['uses' => 'LoginController#getView', 'as' => 'frontend.guest.login']);
Route::post('/login', ['uses' => 'LoginController#onPost', 'as' => 'frontend.guest.login']);
});
How can I get it to stop requiring route 'login' and start requiring my custom one 'frontend.guest.login' ??
First of all, you should fix your following route names:
Route::get('/login', ['uses' => 'LoginController#getView', 'as' => 'frontend.guest.login']);
Route::post('/login', ['uses' => 'LoginController#onPost', 'as' => 'frontend.guest.login']);
Notice that, you've used frontend.guest.login for both (get/post) routes which is wrong, instead you should use unique names for example: frontend.guest.get.login for Route::get() and frontend.guest.post.login for Route::post().
Then, in your App\Exceptions\Handler class, create/override the following method:
protected function unauthenticated($request, AuthenticationException $exception)
{
return $request->expectsJson()
? response()->json(['message' => 'Unauthenticated.'], 401)
: redirect()->guest(route('frontend.guest.get.login'));
}
Also, use the use Illuminate\Auth\AuthenticationException; statement at the top of your class to import AuthenticationException class in your App\Exceptions\Handler.
Also, change every use case of frontend.guest.login to appropriate route name, use frontend.guest.post.login for form submission/action and frontend.guest.get.login to show the form or for the redirect.
This happens because Laravel's default Authenticate middleware throws an AuthenticationException and Laravel's default way to handle this exception is to do this:
return $request->expectsJson()
? response()->json(['message' => $exception->getMessage()], 401)
: redirect()->guest(route('login'));
You will find this code in the unauthenticated method of Illuminate\Foundation\Exceptions\Handler, which your default App\Exceptions\Handler should extend.
You are able to override this behaviour simply by providing your own unauthenticated method in your App\Exceptions\Handler class. For example:
<?php
namespace App\Exceptions;
use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
class Handler extends ExceptionHandler
{
// The rest of your Handler class here...
public function unauthenticated()
{
// Add your implementation here
}
}