chrisbjr / api-guard Goto Github PK
View Code? Open in Web Editor NEWA simple way of authenticating your RESTful APIs with API keys using Laravel
License: MIT License
A simple way of authenticating your RESTful APIs with API keys using Laravel
License: MIT License
Hi,
Are there any plans to create a middleware component for the class instead of having to extend the controller? In a small project, albeit very different, we are dealing with requests that forward on to various other services that cannot be extended by the ApiGuardController
.
I would be willing to contribute this if you're happy to accept the feature?
Cheers
This cost me a bunch of time, and others might benefit from some clarity... I could not get the sample to work using curl and the Authorization header. I finally found the note here (https://docs.auth0.com/server-apis/php-laravel) that, "By default, Apache doesn't provide the Authorization header to the request". Hence, the example code never worked, as it never sat the Authorization header, and always returned unauthorized.
Might want to default to x-authorization for the example, with a pointer on how to make it work with the full "Authorization" header.
This example doesn't work:
$apiKeyGen = new Chrisbjr\ApiGuard\ApiKey;
$newKey = $apiKeyGen->generateKey();
It gives a [Symfony\Component\Debug\Exception\FatalErrorException] Class 'Chrisbjr\ApiGuard\ApiKey' not found
error.
This works fine (note the extra \Models
added):
$apiKeyGen = new Chrisbjr\ApiGuard\Models\ApiKey;
$newKey = $apiKeyGen->generateKey();
Maybe I'm doing something wrong, but thought at least documenting my mistake would be useful to someone in the future. If I made a mistake, maybe in the configuration, can someone point it out?
Thanks.
When accessing my API via http://url.dev/api/v1/events I am returned with all events as you would expect. This works with and without the API key when using the
'keyAuthentication' => false,
However if I try to return just one record with http://url.dev/api/v1/events/3 I get the following even when using the key is switched off:
``{"error":{"code":"GEN-UNAUTHORIZED","http_code":401,"message":"Unauthorized"}}`
My show method -
public function show($id)
{
$event = Ev::find($id);
if(!$event){
return Response::api()->errorNotFound('Event Not Found');
}
return $this->response->withItem($event, new EventTransformer);
}
Any help is appreciated. :)
Steven
i'm using the api-guard in the raravel5. but a little worry that the x-authorization value will be intercepted by some one. anyone can resolve the question for me ?
Hi
I've installed api-guard with Laravel and coupled it with MongoDB instead of MySQL.
But I've some problem : testing with two different browsers, the authentication not working all the time and some users can pass through it when after the first was authenticated.
There is a configuration not set well or there is a session keep ?
Hi, since the last update:
public function initialize()
{
// get user matching to supplied apikey
$user_id = $this->apiKey->user_id;
$this->user = User::findOrFail($user_id);
....
}
Returns: Trying to get property of non-object
Is there a new way of accessing the user_id belonging to the api key provided?
thanks
Hi, I've been working on a project and am implementing functional unit tests with phpunit on laravel 4.2, and I was wondering if you have any hints as to how to get apiguard bootstrapped with the testing framework so I can test against a controller's methods.. Any help would be appreciated!
Thanks,
Geoff
I'm already using Fractal and Api-Response in my api, but I'm using the latest versions of both:
"league/fractal": "0.9.*",
"ellipsesynergie/api-response": "0.7.*",
Will this work with the latest versions?
Hi,
with this package can I set a limit requests for each user or for each type of user?
Example:
Free account : 1.000requests per day
Paid account: 10.000 requests per day
Exclusive account: 100.000 requests
and so on
Thanks!
Hello!
Sorry for my dummy question, but can you explain how to send GET request to http://localhost:8000/api/v1/books in controller method to get data?
How to send curl --header "X-Authorization: 2ed9d72e5596800bf805ca1c735e446df72019ef" http://localhost:8000/api/v1/books in controller method in Laravel 5?
May be something like this:
$response = $this->call('GET', '/api/v1/some-endpoint', [], [], [], ['HTTP_X-Authorization' => 'VALID_TOKEN_HERE']);
but call is not defined : (
Thank you.
The readme says that I'd generally like to use a new key for each user. How can I do that, though, when they're only created through the command line? Would it be bad to rely on one key for all of my API calls?
Caused by a feature in v2.2[5a2676c] because previously, api_key_id
in the api_logs
table is not nullable.
FIX is to set it obviously to nullable
Is there a more elegant way to throw RESTful error responses via the API for validation within a controller? I don't see anything built in for this in ApiGuardController.
For instance, currently in my store method I'm running validation on the data, then tapping directly into the api-response to output any errors which may have occured.
public function store(Request $request)
{
$v = \Validator::make($request->all(), [
'field' => 'required',
]);
if ($v->fails())
{
return $this->response->errorWrongArgs($v->errors());
}
$item = new Item;
$item->field = $request->input('field');
$item->save();
}
I am getting unauthorized error for all requests.
{ "error": { "code": "GEN-UNAUTHORIZED", "http_code": 401, "message": "Unauthorized" } }
Here is my controller.
<?php
use Chrisbjr\ApiGuard\ApiGuardController;
class IncidentsController extends ApiGuardController {
protected $apiMethods = [
'all' => [
'keyAuthentication' => false
],
];
public function all()
{
$books = Incident::find(2);
return $books;
}
}
?>
It works well with 'keyAuthentication' => true.
I am trying it on laravel 4.2
Any help would be appreciated.
Hey there!
Firstly, thanks for the sweet package! It's really making my life much easier =)
I have quite a unique requirement for my application so forgive me if I might have exposed 'non-issues'. I have noticed that the all key is ignored in the apiMethods array. I stepped through your controller and the filter implementation does cater for setting keyAuthentication for all methods with the all key.
Hi,
I started using api-guard to secure my API with keys and limits and it works great !
I just have two issues with it, related to the authorization header:
The first one is that you need to name it x-something if you want the call Request::header(Config::get('api-guard::keyName')); work in ApiGuardController.php line 71 (the default value 'Authorization' does not work).
The second one is when you call your API internally, and try to pass the key as the header of your request, like this:
$request = \Request::create('/my/custom/route/to/my/api/action', 'GET');
$request->headers->set('x-authorization','80c10c72e64eaafc0a644db203432c1f9');
$response = \Route::dispatch($request);
Then the same line in your ApiGuardController.php should be:
$key = Route::getCurrentRequest()->header(Config::get('api-guard::keyName'));
otherwise the request checked is not the good one - which the one we pass to the API.
Do you think you could patch the code with this small change ?
Basically anywhere you call Request::something you should replace it by Route::getCurrentRequest->something to be sure.
Thank you,
On line 15 of the ApiGuardServiceProvider there is this line:
$this->app->register('EllipseSynergie\ApiResponse\Laravel\ResponseServiceProvider');
However, I already use the api-response package for other api methods that don't need guarding. Since I want to use the JSON:API specification, I had made a custom ResponseServiceProvider for api-response, as instructed here.
My question is if it would be possible to provide a way to not register the ResponseServiceProvider. Perhaps include an option to define if the ResponseServiceProvider should be included or not?
I think the url for getting a new token should be
http://localhost:8000/apiguard/generate(according to the source code)
instead of
$ curl -X POST http://localhost:8000/apiguard/api_key as the document says.
It would be very useful if we can create an API key from anywhere inside an application.
Probably, examples and stuff you can do with apiguard should be here. Will be doing when I get more time off my projects. Lol.
But yeah. You can submit PRs and we'll see how it goes. :)
I'm trying to install using a cmdline call to composer because otherwise too much stuff gets changed/breaks...
I've tried many variations of: composer require chrisbjr/api-guard: "~1.0"
( 1.0 1.0@dev 1.1.1 ~1@dev )
but nothing seems to give me anything but:
[InvalidArgumentException]
Could not find package at any version for your minimum-stability (stable). Check the package spelling or your minimum-stability
I also changed y root composer.json to require dev
to no avail
I really want to use your package -- what should I do ?
I've just discovered this package and I managed to get it working but I had an issue with Models.
I don't know if I misconfigured anything but I had this exception raised (typo btw) :
You ApiKey model should be an instance of ApiKeyRepository.
I've noticed you have 2 Models folder with same namespaces for both of the classes ApiKey and ApiLog :
In the autoload_classmap.php that is generated, it takes the 2nd path instead of the 1st one.
Is it normal ? Have I done anything wrong?
Thank you
This isn't an issue as much as a request for help. I couldn't find a forum where this would be better asked.
I'm using the package under Laravel 4.2.11. I've tried the most basic of examples but am unable to get the auth to do anything. This is a contrived example obviously and I wouldn't actually use POST
to get books--I ultimately need to add new rows to a db. Anyway, changing to a GET
makes no difference.
I have installed the package, done the migration and generated a key, and verified they exist.
My controller is:
<?php namespace App\Controllers;
use Chrisbjr\ApiGuard\Controllers\ApiGuardController;
use Response;
use Storage\Book\BookRepository as Book;
class BookController extends ApiGuardController {
protected $book;
public function __construct(
Book $book
) {
$this->book = $book;
}
public function postUpdateBooks() {
return Response::json($this->book->getBooks());
}
}
$this->book->getBooks()
is a call to a model method that returns all books. I'm using the Response
class as discussed in #19.
I then try this using curl (also using Postman):
curl -X POST https://localdev.com/api/v1/books
Rather than trigger an auth error, I get the books JSON return. If I add an incorrect X-Authorization
token, I still get the books JSON. My understanding is all methods automatically have keyAuthentication
enabled, but I still tried adding the protected $apiMethods
property and set it to true
. Still no auth.
I'm getting no errors and the api_logs
table is empty. I'd appreciate any pointers.
Im on laravel 5.1 got this error when trying migrate:reset
PHP Fatal error: Class 'CreateApiKeysTable' not found in /Users/azul/WebRoot/spcapps/vendor/laravel/framework/src/Illuminate/Database/Migrations/Migrator.php on line 324
PHP Stack trace:
PHP 1. {main}() /Users/azul/WebRoot/spcapps/artisan:0
PHP 2. Illuminate\Foundation\Console\Kernel->handle() /Users/azul/WebRoot/spcapps/artisan:36
PHP 3. Symfony\Component\Console\Application->run() /Users/azul/WebRoot/spcapps/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php:100
PHP 4. Symfony\Component\Console\Application->doRun() /Users/azul/WebRoot/spcapps/vendor/symfony/console/Application.php:126
PHP 5. Symfony\Component\Console\Application->doRunCommand() /Users/azul/WebRoot/spcapps/vendor/symfony/console/Application.php:195
PHP 6. Illuminate\Console\Command->run() /Users/azul/WebRoot/spcapps/vendor/symfony/console/Application.php:878
PHP 7. Symfony\Component\Console\Command\Command->run() /Users/azul/WebRoot/spcapps/vendor/laravel/framework/src/Illuminate/Console/Command.php:136
PHP 8. Illuminate\Console\Command->execute() /Users/azul/WebRoot/spcapps/vendor/symfony/console/Command/Command.php:259
PHP 9. Illuminate\Container\Container->call() /Users/azul/WebRoot/spcapps/vendor/laravel/framework/src/Illuminate/Console/Command.php:150
PHP 10. call_user_func_array:{/Users/azul/WebRoot/spcapps/vendor/laravel/framework/src/Illuminate/Container/Container.php:502}() /Users/azul/WebRoot/spcapps/vendor/laravel/framework/src/Illuminate/Container/Container.php:502
PHP 11. Illuminate\Database\Console\Migrations\ResetCommand->fire() /Users/azul/WebRoot/spcapps/vendor/laravel/framework/src/Illuminate/Container/Container.php:502
PHP 12. Illuminate\Database\Migrations\Migrator->reset() /Users/azul/WebRoot/spcapps/vendor/laravel/framework/src/Illuminate/Database/Console/Migrations/ResetCommand.php:69
PHP 13. Illuminate\Database\Migrations\Migrator->runDown() /Users/azul/WebRoot/spcapps/vendor/laravel/framework/src/Illuminate/Database/Migrations/Migrator.php:194
PHP 14. Illuminate\Database\Migrations\Migrator->resolve() /Users/azul/WebRoot/spcapps/vendor/laravel/framework/src/Illuminate/Database/Migrations/Migrator.php:215
[Symfony\Component\Debug\Exception\FatalErrorException]
Class 'CreateApiKeysTable' not found
Hi.
What if we moved code that gets api key from the header outside of
if ($keyAuthentication === true) {
then we could get users api key in request log even if method is turned off for authentication.
I'm building a custom API and I have it set up where a user can login from multiple devices/browsers and I track the sessions. I do this as the web dashboard for the user allows them to log out of other specific or all sessions.
Is there a way to attach the key to the user_id AND session? I am sure this depends on what auth
drivers one is using.
Hi all,
Are there any plans for built-in API-versioning? I've been looking at https://github.com/dingo/api, and it looks great, though a little overkill for what I need. One thing it does have it smart routing around API versions, to declare which API versions specific routes will work for: https://github.com/dingo/api/wiki/Creating-API-Endpoints
That may be out of scope for what this package is trying to do, but anyone who has written a publicly-consumable API knows how quickly versions can get confusing and end up with regression issues. Would be great if something like that could be built-in here.
With the arrival of Laravel 5, the ellipsesynergie/api-response package has been updated to v0.9, which no longer supports Laravel 4.
Since your api-guard requires version "~0.7" of api-response, a composer update now breaks all use of the api-guard package.
Hi chris!
Can i use standard laravel responses instead of fractal?
Thanks!
Hi,
Shouldn't the HTTP Code when you reached the API limit be 429 in staid of 431 ?
429 Too Many Requests
431 Request Header Fields Too Large
P.S I know it's something from the api-response package
Maybe I am missing something, but I don't see how this is actually authenticating anything.
This does not work with any authentication middleware even if the api key is attached to a user.
I have hacked the boilerplate L5 authentication middleware to bind to the user attached to the api key like this:
public function handle($request, Closure $next)
{
if($apiKey = $request->headers->get(Config::get('apiguard.keyName'))){
if($user = $this->userService->getUserByApiKey($apiKey)){
$this->auth->setUser($user);
}
}
if ($this->auth->guest())
{
if ($request->ajax())
{
return response('Unauthorized.', 401);
}
else
{
return redirect()->guest('auth/login');
}
}
return $next($request);
}
}
Am I being totally dense or does this actually not do any authentication?
I just started PHP development with Laravel 5 again, so I hope this isn't some kind of beginners mistake.
I installed api-guard as it is described in the instructions. I used to reset the database and add Test data with artisan migrate:refresh --seed
. But after installing api-guard it fails with the message:
[Symfony\Component\Debug\Exception\FatalErrorException]
Cannot redeclare class CreateApiKeysTable
However, using artisan migrate
and artisan db:seed
seperated works.
Is this an actual issue or just my mistake?
hello,
I would like to know if there is a way to change the connection to use mysql for "apikey" and "Apilog" I mean to add the attribute
protected $connection = 'mysql2';
In the model of "apikey" and "apilog"
I did not see the opportunity to do so in the code or configuration
thank you very much
Sometimes methods are accessible even to lower level api keys users, even though the $apiMethods
array is well configured.
Example:
mymethod is accessible even by level 2 api keys
protected $apiMethods = [
'mymethod' => [
'logged' => false,
'level' => 4,
'limits' => [
'method' => [
'increment' => '1 hour',
'limit' => 50
]
]
],
];
Have you had any issues working locally and doing curl requests with authorization headers?
Here is what I am using:
curl --header "Authorization: 2ed9d72e5596800bf805ca1c735e446df72019ef" http://spire.site/api/v1/sites
(I went ahead and used the same auth key as your example and updated my key in the test DB so I could quickly past this command in).
I am running the site locally using "spire.site" as my host and not localhost:PORT etc. Could this be the issue? I am hopefully already dealing with the CORS issue as I am using a "laravel-cors" provider to ensure I can get API methods allowed for sharing.
Is there another way to test the authorization headers / protected methods?
What would be the best way to revoke an API key?
how would I get the authenticated user id with this API key approach.
I'm trying to make it so that I can use my REST API internally as well as externally.
when using internally the user will be logged in and I'll set the header( I think) unless there is better way to approach this.
Hi,
did anyone tried to authenticate with fiddler? It works with GET when you send X-Authorization=XXX in URL, but how to do it with POST/PUT/DELETE ?
I'm testing with fiddler,because I will use this api in android project.
step as the API key in AJAX or Angle, I'm doing a web application. In postman step Authorization + key and is all right.
but in my application appears 401 (Unauthorized)
I know it is just 1 day after the release, but can you please allow Laravel 5.1 to be installed so we can detect bugs or help you to improve the api-guard for 5.1? Now we cannot install laravel as composer is blocking it by your dependency setting.
Thanks.
Peter
I wanted to see if API Guard was Lumen was compatible, and whilst it isn't yet, I think there's a few small tweaks could enable it. I suspect a lot of it is down to class aliases (as they're not included in Lumen) and some dependancies.
The first step you have to do is uncomment $app->withFacades();
on line 20 in app.php
.
Then the issues are happening when trying to using artisan
to publish the migration and configurations:
Fatal error: Class 'Response' not found in /lumen/vendor/ellipsesynergie/api-response/src/Laravel/ResponseServiceProvider.php on line 29
Line 29 is:
\Response::macro('api', function () {
I would expect that references Laravel's standard Response facade which is fixed with:
\Illuminate\Support\Facades\Response::macro('api', function () {
That appeared to fix it that - but it moved onto another issue when running artisan
:
[Illuminate\Container\BindingResolutionException]
Target [Illuminate\Contracts\Routing\ResponseFactory] is not instantiable.
I've yet to resolve what the problem is with this - does anyone else have any ideas?
Hi all,
I've had success setting up the system and it's working quite well. I do have a small problem. I have extended the model (class ApiKey extends ApiKeyRepository) and after adding the relations to the model referring to my users table, getting the user for the API key works fine through this method in the controllers' functions:
$this->apiKey->user
I would however like to be able to set the user just once in the constructor of the Controller so I can get the authenticated user like $this->user. I've tried adding this to the controller with no success:
class ServersController extends ApiGuardController
{
protected $user;
public function __construct()
{
parent::__construct();
$this->user = $this->apiKey->user;
}
...
Since I'm able to get to this data from any of the functions, I'm wondering why this doesn't seem possible in the constructor. I am likely overlooking something obvious here... When I dump the value of $this->apiKey in the constructor I get null as the value for some reason.
Any help would be very appreciated!
Cheers,
/K
In "Using" part of documentation path to ApiGuardController is wrong. Controller folder is missing and you get "ApiGuardController not found" error.
Regards,
Rok
Well, it's a thought. It would be nice if api-guard does only one thing after all.
If @chrisbjr agrees, then we'd do 3.0
. Also thinking of making options about how we do auth, eg. JWT.
For security purposes?
Hi @chrisbjr,
I've just installed api-guard
without issue but I don't have any error message to protect my API.
Here is my controller:
<?php namespace App\Http\Controllers;
use Chrisbjr\ApiGuard\Http\Controllers\ApiGuardController;
use App\Model\Repositories\CollaboratorRepository;
class CollaboratorController extends ApiGuardController {
private $collaborator_repository;
public function __construct(CollaboratorRepository $collaborator_repository)
{
$this->collaborator_repository = $collaborator_repository;
}
public function getAll ()
{
$collaborators = $this->collaborator_repository->getAll();
return response()->json($collaborators);
}
public function getById ($id)
{
$collaborator = $this->collaborator_repository->getById($id);
return response()->json($collaborator);
}
}
I get my JSON but I expected errors because I didn't provide the X-Authorization
header.
I have your 2 tables and generated an API key.
Bests
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.