Skip to content

Document authentication #43

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 22, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 185 additions & 0 deletions docs/components/authentication.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
# Authentication

The Authentication component allows you to to implement authentication methods which can simply update the request
with authentication detail (for example by adding an `Authorization` header).
This is useful when you have to send multiple requests to the same endpoint. Using an authentication implementation,
these details can be separated from the actual requests.


## Installation

```
$ composer require php-http/message
```


## Authentication methods

General usage looks like the following:

``` php
$authentication = new AuthenticationMethod();

/** @var Psr\Http\Message\RequestInterface */
$authentication->authenticate($request);
```


### Basic Auth

This authentication method accepts two parameters: username and password. Getters/Setters are provided by
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would mention that this is using the Authorization header of the HTTP specification.

`Http\Message\Authentication\UserPasswordPair` trait.

``` php
use Http\Message\Authentication\BasicAuth;

$authentication = new BasicAuth('username', 'password');

// These details can be set later as well
// There are also getters with the appropriate method names
$authentication->setUsername('username');
$authentication->setPassword('password');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually why? having this immutable would seem cleaner to me.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, you are right. I wonder if we need getters at all.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, shouldn't we keep the mutability of the Chain method? It's some sort of builder class after all.

```


### Bearer

This authentication method accepts one parameter: a token.

``` php
use Http\Message\Authentication\Bearer;

$authentication = new Bearer('token');

// Token can be set later as well
$authentication->setToken('token');
```


### Chain
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

chain and matching are not really authentication methods, but meta tools to work with authentication. i would separate them with a ## level title.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved them to the end of the list. With the table reorganization, I don't think we need to separate them in the examples.


This authentication method accepts one parameter: an array of other authentication methods.

The idea behind this authentication method is that in some cases you might need to
authenticate the request with multiple methods.

For example it's a common practice to protect development APIs with Basic Auth and the regular token auth as well
to protect the API from unnecessary processing.


``` php
use Http\Message\Authentication\Chain;

$authenticationChain = [
new AuthenticationMethod1(),
new AuthenticationMethod2(),
];

$authentication = new Chain($authenticationChain);

// Authentication chain can be modified later
$authenticationChain = $authentication->getAuthenticationChain();

array_pop($authenticationChain);

$authentication->setAuthenticationChain($authenticationChain);

$authentication->clearAuthenticationChain();

$authentication->addAuthentication(new AuthenticationMethod3());
```


### Matching

With this authentication method you can conditionally add authentication details to your request by passing a callable
to it. When a request is passed, the callable is called and used as a boolean value in order to decide whether
the request should be authenticated or not.
It also accepts an authentication method instance which does the actual authentication when the condition is
fulfilled.

For example a common use case is to authenticate requests sent to certain paths.


``` php
use Http\Message\Authentication\Mathing;

$authentication = new Mathing(new AuthenticationMethod1(), function () { return true; });
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mathing or Matching?

i would make the example a real one, matching for only some domain. then we would see how the matching callback is passed the request (i guess?) and does a real check on it.


// There are also getters with the appropriate method names
$authentication->setAuthentication(new AuthenticationMethod2());
$authentication->setMatcher(function () { return false; });
```


In order to ease creating matchers for URLs/paths, there is a static factory method for this purpose.
The first argument is an authentication method, the second is a regexp to match against the URL.


``` php
use Http\Message\Authentication\Mathing;

$authentication = Matching::createUrlMatcher(new AuthenticationMethod(), '\/api');
```


### Query Params

Add authentication details as URL Query params:

`http://api.example.com/endpoint?access_token=9zh987g86fg87gh978hg9g79`


``` php
use Http\Authentication\QueryParams;

$authentication = new QueryParams([
'access_token' => '9zh987g86fg87gh978hg9g79',
]);
```

!!! warning "Warning:"
Using query parameters for authentication is not safe.
Only use it when absolutely necessary.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only use it when this is the only authentication method offered by a third party application.



### WSSE

This method implements [WSSE Authentication](http://www.xml.com/pub/a/2003/12/17/dive.html).
Just like Basic Auth, it also accepts a username-password pair and exposes the same methods as well.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i like the link to the standard. we should do that for all methods. not sure if the spec is the right place, or wikipedia might be easier to read. but we should link them to something.

also, we might order these methods semantically rather than alphabetically, and put this next to basic auth.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but I there are no Bearer and WSSE pages. There is OAuth and WS-Security which are related, but not the same.



``` php
use Http\Message\Authentication\Wsse;

$authentication = new Wsse('username', 'password');
```


## Implement your own

Implementing an authentication method is easy: only one method needs to be implemented.

``` php
use Http\Message\Authentication\Authentication;
use Psr\Http\Message\RequestInterface;

class MyAuth implements Authentication
{
public function authenticate(RequestInterface $request)
{
// do something with the request

// keep in mind that the request is immutable!
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

// keep in mind that the request is immutable - return the updated version of the request with the authentication information added to it.

return $request;
}
}
```


## Integration with HTTPlug

Normally requests must be authenticated "by hand" which is not really convenient.

If you use HTTPlug, you can integrate this component into the client using the
[authentication plugin](/httplug/plugins/authentication).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i would mention the authentication plugin in the introduction as well.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved this section up, so that it is visible when you open the page.

15 changes: 14 additions & 1 deletion docs/httplug/plugins/authentication.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
# Authentication Plugin

TODO: explain the authentication plugin
This plugin uses the [authentication component](/components/authentication) to authenticate all requests sent through
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/authenticate all requests/authenticate requests/

we have the filter thingy that allows to only authenticate some requests rather than all.

the client.


## Usage

``` php
use Http\Plugins\PluginClient;
use Http\Plugins\AuthenticationPlugin;

$pluginClient = new PluginClient(new HttpClient(), [new AuthenticationPlugin(new AuthenticationMethod()]);
```

Check the [component documentation](/components/authentication) for the list of available authentication methods.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/component documentation/authentication component documentation/