-
Notifications
You must be signed in to change notification settings - Fork 2
Description
Repo: https://github.com/wordpress/application-passwords
@TimothyBJacobs asked me to write up an issue about the work already done on Application Passwords, so here we go:
User Flow : New App
The flow is as simple as an app linking to your.site/wp-admin/?path=auth_app
with a number of optional get strings appended to it. This ensures that if the user isn't already logged in, the request arguments get preserved through the authentication flow:
app_name
(required) - The human readable identifier for your app. This will be the name of the generated application password, so structure it like ... "WordPress Mobile App on iPhone 12" for uniqueness between multiple versions. If omitted, the user will be required to provide an application name.success_url
(recommended) - The URL that you'd like the user to be sent to if they approve the connection. Two GET variables will be appended when they are passed back --user_login
andpassword
-- these credentials can then be used for API calls. If thesuccess_url
variable is omitted, a password will be generated and displayed to the user, to manually enter into your application.reject_url
(optional) - If included, the user will get sent there if they reject the connection. If omitted, the user will be sent to thesuccess_url
, with?success=false
appended to the end. If thesuccess_url
is omitted, the user will be sent to their dashboard.
The UI looks something like this:
and when the user completes the flow, they can be redirected back to the url they came from, or even directly back into the app requesting authorization via custom app protocols.
The flow is accomplished and made smoother via javascript / ajax requests, however will operate just fine via traditional form submissions if JS is disabled in the browser for any reason.
Managing existing app passwords
The user profile page panel for managing application passwords looks like this:
It can be used to generate new passwords directly, but for auth requests from an external website or app it's much better ux to use the previous flow.
The table is managed and updated via jQuery for dom queries/insertions/deletions, and wp.template
for generating the markup. It should be trivially rewritable into React if there's a need to expand React usage in the admin.
Data
The generated application passwords are 24 characters long to ensure over 128 bits of entropy (we're actually at over 142 bits of entropy -- 62^24), and have their hashes stored in usermeta under the _application_passwords
key.
Application Passwords are stored in the database as an array of arrays under the aforementioned key.
Each entry consists of the following properties:
name
-- The designated application name given when the password was created. Not guaranteed to be unique.password
-- The password's hash, viawp_hash_password()
created
-- Thetime()
that the password was created.last_used
-- Thetime()
that the password was used most recently. Can be useful for finding and clearing out old passwords no longer in use.last_ip
-- The$_SERVER['REMOTE_ADDR']
that most recently used the application password. This can be a very useful audit trail to identify if it has been used improperly.
Authentication
Application Passwords explicitly only work for REST API or XML-RPC authentication. They can not be used and will not function when attempting an interactive login via wp-login.php or the like.
REST API Support
The existing application-passwords plugin fully supports the REST API, offering endpoints to list, add new application passwords, and delete one or all application passwords for a given user.
DON'T PANIC
The application-passwords repository has a lot of random files in it. Most of these were added for automated testing and such and can be ignored. The only relevant files in it to understand what's going on are:
application-passwords.css
-- general stylesapplication-passwords.js
-- js for the profile page listing uiapplication-passwords.php
-- basic plugin loader -- just loads the class and kicks it offauth-app.js
-- js for the auth flow uiclass.application-passwords-list-table.php
-- list table for the profile page -- minimalclass.application-passwords.php
-- most of the hard work. well commented, phpdoc, etc.
In Summation
Some of the most relevant wins I see here with Application Passwords are:
- Application Passwords can only be used for API requests, never for getting a full wp-admin login.
- Doesn't require password storage. Applications integrating with WordPress never see the user's actual password.
- Application Passwords are high-entropy, and fully revokable.
- Very easy implementation. No libraries needed, as the username and password can be passed via standard basic auth (as supported by curl already). Handles FastCGI incompatability by using .htaccess to rewrite to a different authentication header, and then catches via a fallback.
- Backward Compatible with XML-RPC! The generated credentials can be used as a drop in replacement for legacy apps that use XML-RPC, and also enables apps doing new integrations to query legacy XML-RPC endpoints if needed for any reason.