vapor-docs/build/3.0/auth/api/index.html

2480 lines
65 KiB
HTML

<!DOCTYPE html>
<html lang="en" class="no-js">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<link rel="canonical" href="https://docs.vapor.codes/3.0/auth/api/">
<meta name="lang:clipboard.copy" content="Copy to clipboard">
<meta name="lang:clipboard.copied" content="Copied to clipboard">
<meta name="lang:search.language" content="en">
<meta name="lang:search.pipeline.stopwords" content="True">
<meta name="lang:search.pipeline.trimmer" content="True">
<meta name="lang:search.result.none" content="No matching documents">
<meta name="lang:search.result.one" content="1 matching document">
<meta name="lang:search.result.other" content="# matching documents">
<meta name="lang:search.tokenizer" content="[\s\-]+">
<link rel="shortcut icon" href="../../assets/images/favicon.png">
<meta name="generator" content="mkdocs-1.0.4, mkdocs-material-3.0.6">
<title>Stateless (API) - Vapor Docs</title>
<link rel="stylesheet" href="../../assets/stylesheets/application.451f80e5.css">
<link rel="stylesheet" href="../../assets/stylesheets/application-palette.22915126.css">
<meta name="theme-color" content="#2196f3">
<link rel="stylesheet" type="text/css" href="../../styles/carbon.css">
<script src="../../assets/javascripts/modernizr.1aa3b519.js"></script>
<script src="../../scripts/carbon.js"></script>
<link href="https://fonts.gstatic.com" rel="preconnect" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,400i,700|Roboto+Mono">
<style>body,input{font-family:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif}code,kbd,pre{font-family:"Roboto Mono","Courier New",Courier,monospace}</style>
<link rel="stylesheet" href="../../assets/fonts/material-icons.css">
</head>
<body dir="ltr" data-md-color-primary="blue" data-md-color-accent="purple">
<svg class="md-svg">
<defs>
<svg xmlns="http://www.w3.org/2000/svg" width="416" height="448"
viewBox="0 0 416 448" id="__github">
<path fill="currentColor" d="M160 304q0 10-3.125 20.5t-10.75 19-18.125
8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19 18.125-8.5
18.125 8.5 10.75 19 3.125 20.5zM320 304q0 10-3.125 20.5t-10.75
19-18.125 8.5-18.125-8.5-10.75-19-3.125-20.5 3.125-20.5 10.75-19
18.125-8.5 18.125 8.5 10.75 19 3.125 20.5zM360
304q0-30-17.25-51t-46.75-21q-10.25 0-48.75 5.25-17.75 2.75-39.25
2.75t-39.25-2.75q-38-5.25-48.75-5.25-29.5 0-46.75 21t-17.25 51q0 22 8
38.375t20.25 25.75 30.5 15 35 7.375 37.25 1.75h42q20.5 0
37.25-1.75t35-7.375 30.5-15 20.25-25.75 8-38.375zM416 260q0 51.75-15.25
82.75-9.5 19.25-26.375 33.25t-35.25 21.5-42.5 11.875-42.875 5.5-41.75
1.125q-19.5 0-35.5-0.75t-36.875-3.125-38.125-7.5-34.25-12.875-30.25-20.25-21.5-28.75q-15.5-30.75-15.5-82.75
0-59.25 34-99-6.75-20.5-6.75-42.5 0-29 12.75-54.5 27 0 47.5 9.875t47.25
30.875q36.75-8.75 77.25-8.75 37 0 70 8 26.25-20.5
46.75-30.25t47.25-9.75q12.75 25.5 12.75 54.5 0 21.75-6.75 42 34 40 34
99.5z" />
</svg>
</defs>
</svg>
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
<label class="md-overlay" data-md-component="overlay" for="__drawer"></label>
<a href="#api-authentication" tabindex="1" class="md-skip">
Skip to content
</a>
<header class="md-header" data-md-component="header">
<nav class="md-header-nav md-grid">
<div class="md-flex">
<div class="md-flex__cell md-flex__cell--shrink">
<a href="https://docs.vapor.codes/3.0/" title="Vapor Docs" class="md-header-nav__button md-logo">
<img src="../../images/droplet-white.svg" width="24" height="24">
</a>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--menu md-header-nav__button" for="__drawer"></label>
</div>
<div class="md-flex__cell md-flex__cell--stretch">
<div class="md-flex__ellipsis md-header-nav__title" data-md-component="title">
<span class="md-header-nav__topic">
Vapor Docs
</span>
<span class="md-header-nav__topic">
Stateless (API)
</span>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<label class="md-icon md-icon--search md-header-nav__button" for="__search"></label>
<div class="md-search" data-md-component="search" role="dialog">
<label class="md-search__overlay" for="__search"></label>
<div class="md-search__inner" role="search">
<form class="md-search__form" name="search">
<input type="text" class="md-search__input" name="query" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="query" data-md-state="active">
<label class="md-icon md-search__icon" for="__search"></label>
<button type="reset" class="md-icon md-search__icon" data-md-component="reset" tabindex="-1">
&#xE5CD;
</button>
</form>
<div class="md-search__output">
<div class="md-search__scrollwrap" data-md-scrollfix>
<div class="md-search-result" data-md-component="result">
<div class="md-search-result__meta">
Type to start searching
</div>
<ol class="md-search-result__list"></ol>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<div class="md-header-nav__source">
<a href="http://github.com/vapor/vapor/" title="Go to repository" class="md-source" data-md-source="github">
<div class="md-source__icon">
<svg viewBox="0 0 24 24" width="24" height="24">
<use xlink:href="#__github" width="24" height="24"></use>
</svg>
</div>
<div class="md-source__repository">
GitHub
</div>
</a>
</div>
</div>
</div>
</nav>
</header>
<div class="md-container">
<main class="md-main">
<div class="md-main__inner md-grid" data-md-component="container">
<div class="md-sidebar md-sidebar--primary" data-md-component="navigation">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--primary" data-md-level="0">
<label class="md-nav__title md-nav__title--site" for="__drawer">
<a href="https://docs.vapor.codes/3.0/" title="Vapor Docs" class="md-nav__button md-logo">
<img src="../../images/droplet-white.svg" width="48" height="48">
</a>
Vapor Docs
</label>
<div class="md-nav__source">
<a href="http://github.com/vapor/vapor/" title="Go to repository" class="md-source" data-md-source="github">
<div class="md-source__icon">
<svg viewBox="0 0 24 24" width="24" height="24">
<use xlink:href="#__github" width="24" height="24"></use>
</svg>
</div>
<div class="md-source__repository">
GitHub
</div>
</a>
</div>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../.." title="Overview" class="md-nav__link">
Overview
</a>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-2" type="checkbox" id="nav-2">
<label class="md-nav__link" for="nav-2">
Install
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-2">
Install
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../install/macos/" title="macOS" class="md-nav__link">
macOS
</a>
</li>
<li class="md-nav__item">
<a href="../../install/ubuntu/" title="Ubuntu" class="md-nav__link">
Ubuntu
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-3" type="checkbox" id="nav-3">
<label class="md-nav__link" for="nav-3">
Getting Started
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-3">
Getting Started
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../getting-started/hello-world/" title="Hello, world" class="md-nav__link">
Hello, world
</a>
</li>
<li class="md-nav__item">
<a href="../../getting-started/toolbox/" title="Toolbox" class="md-nav__link">
Toolbox
</a>
</li>
<li class="md-nav__item">
<a href="../../getting-started/spm/" title="SPM" class="md-nav__link">
SPM
</a>
</li>
<li class="md-nav__item">
<a href="../../getting-started/xcode/" title="Xcode" class="md-nav__link">
Xcode
</a>
</li>
<li class="md-nav__item">
<a href="../../getting-started/structure/" title="Folder Structure" class="md-nav__link">
Folder Structure
</a>
</li>
<li class="md-nav__item">
<a href="../../getting-started/application/" title="Application" class="md-nav__link">
Application
</a>
</li>
<li class="md-nav__item">
<a href="../../getting-started/controllers/" title="Controllers" class="md-nav__link">
Controllers
</a>
</li>
<li class="md-nav__item">
<a href="../../getting-started/routing/" title="Routing" class="md-nav__link">
Routing
</a>
</li>
<li class="md-nav__item">
<a href="../../getting-started/content/" title="Content" class="md-nav__link">
Content
</a>
</li>
<li class="md-nav__item">
<a href="../../getting-started/async/" title="Async" class="md-nav__link">
Async
</a>
</li>
<li class="md-nav__item">
<a href="../../getting-started/services/" title="Services" class="md-nav__link">
Services
</a>
</li>
<li class="md-nav__item">
<a href="../../getting-started/cloud/" title="Deployment" class="md-nav__link">
Deployment
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-4" type="checkbox" id="nav-4">
<label class="md-nav__link" for="nav-4">
Async
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-4">
Async
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../async/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../async/overview/" title="Overview" class="md-nav__link">
Overview
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-5" type="checkbox" id="nav-5" checked>
<label class="md-nav__link" for="nav-5">
Auth
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-5">
Auth
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-toggle md-nav__toggle" data-md-toggle="toc" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
Stateless (API)
</label>
<a href="./" title="Stateless (API)" class="md-nav__link md-nav__link--active">
Stateless (API)
</a>
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#concept" title="Concept" class="md-nav__link">
Concept
</a>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#authorization-header" title="Authorization Header" class="md-nav__link">
Authorization Header
</a>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#basic" title="Basic" class="md-nav__link">
Basic
</a>
</li>
<li class="md-nav__item">
<a href="#bearer" title="Bearer" class="md-nav__link">
Bearer
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#middleware" title="Middleware" class="md-nav__link">
Middleware
</a>
</li>
<li class="md-nav__item">
<a href="#model" title="Model" class="md-nav__link">
Model
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#methods" title="Methods" class="md-nav__link">
Methods
</a>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#password-authentication" title="Password Authentication" class="md-nav__link">
Password Authentication
</a>
</li>
<li class="md-nav__item">
<a href="#token-authentication" title="Token Authentication" class="md-nav__link">
Token Authentication
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#__comments" title="Comments" class="md-nav__link md-nav__link--active">
Comments
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../web/" title="Sessions (Web)" class="md-nav__link">
Sessions (Web)
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-6" type="checkbox" id="nav-6">
<label class="md-nav__link" for="nav-6">
Console
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-6">
Console
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../console/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../console/overview/" title="Overview" class="md-nav__link">
Overview
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-7" type="checkbox" id="nav-7">
<label class="md-nav__link" for="nav-7">
Command
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-7">
Command
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../command/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../command/overview/" title="Overview" class="md-nav__link">
Overview
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-8" type="checkbox" id="nav-8">
<label class="md-nav__link" for="nav-8">
Crypto
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-8">
Crypto
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../crypto/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../crypto/digests/" title="Digests" class="md-nav__link">
Digests
</a>
</li>
<li class="md-nav__item">
<a href="../../crypto/ciphers/" title="Ciphers" class="md-nav__link">
Ciphers
</a>
</li>
<li class="md-nav__item">
<a href="../../crypto/asymmetric/" title="Asymmetric" class="md-nav__link">
Asymmetric
</a>
</li>
<li class="md-nav__item">
<a href="../../crypto/random/" title="Random" class="md-nav__link">
Random
</a>
</li>
<li class="md-nav__item">
<a href="../../crypto/otp/" title="TOTP & HOTP" class="md-nav__link">
TOTP & HOTP
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-9" type="checkbox" id="nav-9">
<label class="md-nav__link" for="nav-9">
Database Kit
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-9">
Database Kit
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../database-kit/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../database-kit/overview/" title="Overview" class="md-nav__link">
Overview
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-10" type="checkbox" id="nav-10">
<label class="md-nav__link" for="nav-10">
Fluent
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-10">
Fluent
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../fluent/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../fluent/models/" title="Models" class="md-nav__link">
Models
</a>
</li>
<li class="md-nav__item">
<a href="../../fluent/querying/" title="Querying" class="md-nav__link">
Querying
</a>
</li>
<li class="md-nav__item">
<a href="../../fluent/migrations/" title="Migrations" class="md-nav__link">
Migrations
</a>
</li>
<li class="md-nav__item">
<a href="../../fluent/relations/" title="Relations" class="md-nav__link">
Relations
</a>
</li>
<li class="md-nav__item">
<a href="../../fluent/transaction/" title="Transaction" class="md-nav__link">
Transaction
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-11" type="checkbox" id="nav-11">
<label class="md-nav__link" for="nav-11">
HTTP
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-11">
HTTP
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../http/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../http/client/" title="Client" class="md-nav__link">
Client
</a>
</li>
<li class="md-nav__item">
<a href="../../http/server/" title="Server" class="md-nav__link">
Server
</a>
</li>
<li class="md-nav__item">
<a href="../../http/message/" title="Message" class="md-nav__link">
Message
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-12" type="checkbox" id="nav-12">
<label class="md-nav__link" for="nav-12">
JWT
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-12">
JWT
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../jwt/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../jwt/overview/" title="Overview" class="md-nav__link">
Overview
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-13" type="checkbox" id="nav-13">
<label class="md-nav__link" for="nav-13">
Leaf
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-13">
Leaf
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../leaf/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../leaf/overview/" title="Overview" class="md-nav__link">
Overview
</a>
</li>
<li class="md-nav__item">
<a href="../../leaf/custom-tags/" title="Custom tags" class="md-nav__link">
Custom tags
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-14" type="checkbox" id="nav-14">
<label class="md-nav__link" for="nav-14">
Logging
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-14">
Logging
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../logging/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../logging/overview/" title="Overview" class="md-nav__link">
Overview
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-15" type="checkbox" id="nav-15">
<label class="md-nav__link" for="nav-15">
Multipart
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-15">
Multipart
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../multipart/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../multipart/overview/" title="Overview" class="md-nav__link">
Overview
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-16" type="checkbox" id="nav-16">
<label class="md-nav__link" for="nav-16">
MySQL
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-16">
MySQL
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../mysql/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-17" type="checkbox" id="nav-17">
<label class="md-nav__link" for="nav-17">
PostgreSQL
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-17">
PostgreSQL
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../postgresql/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-18" type="checkbox" id="nav-18">
<label class="md-nav__link" for="nav-18">
Redis
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-18">
Redis
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../redis/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../redis/overview/" title="Overview" class="md-nav__link">
Overview
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-19" type="checkbox" id="nav-19">
<label class="md-nav__link" for="nav-19">
Routing
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-19">
Routing
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../routing/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../routing/overview/" title="Overview" class="md-nav__link">
Overview
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-20" type="checkbox" id="nav-20">
<label class="md-nav__link" for="nav-20">
Service
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-20">
Service
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../service/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../service/services/" title="Services" class="md-nav__link">
Services
</a>
</li>
<li class="md-nav__item">
<a href="../../service/provider/" title="Provider" class="md-nav__link">
Provider
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-21" type="checkbox" id="nav-21">
<label class="md-nav__link" for="nav-21">
SQL
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-21">
SQL
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../sql/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../sql/overview/" title="Overview" class="md-nav__link">
Overview
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-22" type="checkbox" id="nav-22">
<label class="md-nav__link" for="nav-22">
SQLite
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-22">
SQLite
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../sqlite/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-23" type="checkbox" id="nav-23">
<label class="md-nav__link" for="nav-23">
Template Kit
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-23">
Template Kit
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../template-kit/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-24" type="checkbox" id="nav-24">
<label class="md-nav__link" for="nav-24">
Testing
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-24">
Testing
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../testing/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-25" type="checkbox" id="nav-25">
<label class="md-nav__link" for="nav-25">
URL-Encoded Form
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-25">
URL-Encoded Form
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../url-encoded-form/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../url-encoded-form/overview/" title="Overview" class="md-nav__link">
Overview
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-26" type="checkbox" id="nav-26">
<label class="md-nav__link" for="nav-26">
Validation
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-26">
Validation
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../validation/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../validation/overview/" title="Overview" class="md-nav__link">
Overview
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-27" type="checkbox" id="nav-27">
<label class="md-nav__link" for="nav-27">
Vapor
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-27">
Vapor
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../vapor/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../vapor/client/" title="Client" class="md-nav__link">
Client
</a>
</li>
<li class="md-nav__item">
<a href="../../vapor/content/" title="Content" class="md-nav__link">
Content
</a>
</li>
<li class="md-nav__item">
<a href="../../vapor/sessions/" title="Sessions" class="md-nav__link">
Sessions
</a>
</li>
<li class="md-nav__item">
<a href="../../vapor/websocket/" title="WebSocket" class="md-nav__link">
WebSocket
</a>
</li>
<li class="md-nav__item">
<a href="../../vapor/middleware/" title="Middleware" class="md-nav__link">
Middleware
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-28" type="checkbox" id="nav-28">
<label class="md-nav__link" for="nav-28">
WebSocket
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-28">
WebSocket
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../websocket/getting-started/" title="Getting Started" class="md-nav__link">
Getting Started
</a>
</li>
<li class="md-nav__item">
<a href="../../websocket/overview/" title="Overview" class="md-nav__link">
Overview
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-29" type="checkbox" id="nav-29">
<label class="md-nav__link" for="nav-29">
Extras
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-29">
Extras
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../extras/style-guide/" title="Style Guide" class="md-nav__link">
Style Guide
</a>
</li>
<li class="md-nav__item">
<a href="../../extras/yeoman/" title="Yeoman" class="md-nav__link">
Yeoman
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item md-nav__item--nested">
<input class="md-toggle md-nav__toggle" data-md-toggle="nav-30" type="checkbox" id="nav-30">
<label class="md-nav__link" for="nav-30">
Version (3.0)
</label>
<nav class="md-nav" data-md-component="collapsible" data-md-level="1">
<label class="md-nav__title" for="nav-30">
Version (3.0)
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../version/1_5/" title="1.5" class="md-nav__link">
1.5
</a>
</li>
<li class="md-nav__item">
<a href="../../version/2_0/" title="2.0" class="md-nav__link">
2.0
</a>
</li>
<li class="md-nav__item">
<a href="../../version/3_0/" title="3.0" class="md-nav__link">
3.0
</a>
</li>
<li class="md-nav__item">
<a href="../../version/upgrading/" title="Upgrading" class="md-nav__link">
Upgrading
</a>
</li>
<li class="md-nav__item">
<a href="../../version/support/" title="Support" class="md-nav__link">
Support
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-sidebar md-sidebar--secondary" data-md-component="toc">
<div class="md-sidebar__scrollwrap">
<div class="md-sidebar__inner">
<nav class="md-nav md-nav--secondary">
<label class="md-nav__title" for="__toc">Table of contents</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="#concept" title="Concept" class="md-nav__link">
Concept
</a>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#authorization-header" title="Authorization Header" class="md-nav__link">
Authorization Header
</a>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#basic" title="Basic" class="md-nav__link">
Basic
</a>
</li>
<li class="md-nav__item">
<a href="#bearer" title="Bearer" class="md-nav__link">
Bearer
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#middleware" title="Middleware" class="md-nav__link">
Middleware
</a>
</li>
<li class="md-nav__item">
<a href="#model" title="Model" class="md-nav__link">
Model
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#methods" title="Methods" class="md-nav__link">
Methods
</a>
<nav class="md-nav">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#password-authentication" title="Password Authentication" class="md-nav__link">
Password Authentication
</a>
</li>
<li class="md-nav__item">
<a href="#token-authentication" title="Token Authentication" class="md-nav__link">
Token Authentication
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#__comments" title="Comments" class="md-nav__link md-nav__link--active">
Comments
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content">
<article class="md-content__inner md-typeset">
<a href="https://github.com/vapor/documentation/edit/master/3.0/docs/auth/api.md" title="Edit this page" class="md-icon md-content__icon">&#xE3C9;</a>
<h1 id="api-authentication">API Authentication<a class="headerlink" href="#api-authentication" title="Permanent link">&para;</a></h1>
<p>This guide will introduce you to stateless authentication&mdash;a method of authentication commonly used for protecting API endpoints. </p>
<h2 id="concept">Concept<a class="headerlink" href="#concept" title="Permanent link">&para;</a></h2>
<p>In Computer Science (especially web frameworks), the concept of Authentication means verifying the <em>identity</em> of a user. This is not to be confused with Authorization which verifies <em>privileges</em> to a given resource</p>
<p>This package allows you to implement stateless authorization using the following tools:</p>
<ul>
<li><em><code>"Authorization"</code> header</em>: Used to send credentials in an HTTP request.</li>
<li><em>Middleware</em>: Detects credentials in request and fetches authenticated user.</li>
<li><em>Model</em>: Represents an authenticated user and its identifying information. </li>
</ul>
<h3 id="authorization-header">Authorization Header<a class="headerlink" href="#authorization-header" title="Permanent link">&para;</a></h3>
<p>This packages makes use of two common authorization header formats: basic and bearer.</p>
<h4 id="basic">Basic<a class="headerlink" href="#basic" title="Permanent link">&para;</a></h4>
<p>Basic authorization contains a username and password. They are joined together by a <code>:</code> and then base64 encoded. </p>
<p>A basic authorization header containing the username <code>Alladin</code> and password <code>OpenSesame</code> would look like this:</p>
<div class="codehilite"><pre><span></span><span class="err">Authorization: Basic QWxhZGRpbjpPcGVuU2VzYW1l</span>
</pre></div>
<p>Although basic authorization can be used to authenticate each request to your server, most web applications usually create an ephemeral token for this purpose instead. </p>
<h4 id="bearer">Bearer<a class="headerlink" href="#bearer" title="Permanent link">&para;</a></h4>
<p>Bearer authorization simply contains a token. A bearer authorization header containing the token <code>cn389ncoiwuencr</code> would look like this:</p>
<div class="codehilite"><pre><span></span><span class="err">Authorization: Bearer cn389ncoiwuencr</span>
</pre></div>
<p>The bearer authorization header is very common in APIs since it can be sent easily with each request and contain an ephemeral token. </p>
<h3 id="middleware">Middleware<a class="headerlink" href="#middleware" title="Permanent link">&para;</a></h3>
<p>The usage of Middleware is critical to this package. If you are not familiar with how Middleware works in Vapor, feel free to brush up by reading <a href="../../vapor/middleware/">Vapor &rarr; Middleware</a>.</p>
<p>Authentication middleware is responsible for reading the credentials from the request and fetching the identifier user. This usually means checking the <code>"Authorization"</code> header, parsing the credentials, and doing a database lookup. </p>
<p>For each model / authentication method you use, you will add one middleware to your application. All of this package's middlewares are composable, meaning you can add multiple middlewares to one route and they will work together. If one middleware fails to authorize a user, it will simply forward the request for the next middleware to try.</p>
<p>If you would like to ensure that a certain model's authentication has succeeded <em>before</em> running your route, you must add an instance of <a href="https://api.vapor.codes/auth/latest/Authentication/Classes/GuardAuthenticationMiddleware.html"><code>GuardAuthenticationMiddleware</code></a>.</p>
<h3 id="model">Model<a class="headerlink" href="#model" title="Permanent link">&para;</a></h3>
<p>Fluent models are <em>what</em> the middlewares authenticate. Learn more about models by reading <a href="../../fluent/models/">Fluent &rarr; Models</a>. If authentication is succesful, the middleware will have fetched your model from the database and stored it on the request. This means you can access an authenticated model synchronously in your route. </p>
<p>In your route closure, you use the following methods to check for authentication:</p>
<ul>
<li><code>authenticated(_:)</code>: Returns type if authenticated, <code>nil</code> if not.</li>
<li><code>isAuthenticated(_:)</code>: Returns <code>true</code> if supplied type is authenticated.</li>
<li><code>requireAuthenticated(_:)</code>: Returns type if authenticated, <code>throws</code> if not.</li>
</ul>
<p>Typical usage looks like the following:</p>
<div class="codehilite"><pre><span></span><span class="c1">// use middleware to protect a group</span>
<span class="kd">let</span> <span class="nv">protectedGroup</span> <span class="p">=</span> <span class="n">router</span><span class="p">.</span><span class="n">group</span><span class="p">(...)</span>
<span class="c1">// add a protected route</span>
<span class="n">protectedGroup</span><span class="p">.</span><span class="kr">get</span><span class="p">(</span><span class="s">&quot;test&quot;</span><span class="p">)</span> <span class="p">{</span> <span class="n">req</span> <span class="k">in</span>
<span class="c1">// require that a User has been authed by middleware or throw</span>
<span class="kd">let</span> <span class="nv">user</span> <span class="p">=</span> <span class="k">try</span> <span class="n">req</span><span class="p">.</span><span class="n">requireAuthenticated</span><span class="p">(</span><span class="n">User</span><span class="p">.</span><span class="kc">self</span><span class="p">)</span>
<span class="c1">// say hello to the user</span>
<span class="k">return</span> <span class="s">&quot;Hello, </span><span class="si">\(</span><span class="n">user</span><span class="p">.</span><span class="n">name</span><span class="si">)</span><span class="s">.&quot;</span>
<span class="p">}</span>
</pre></div>
<h2 id="methods">Methods<a class="headerlink" href="#methods" title="Permanent link">&para;</a></h2>
<p>This package supports two basic types of stateless authentication. </p>
<ul>
<li><em>Token</em>: Uses the bearer authorization header.</li>
<li><em>Password</em>: Uses the basic authorization header.</li>
</ul>
<p>For each authentication type, there is a separate middleware and model protocol.</p>
<h3 id="password-authentication">Password Authentication<a class="headerlink" href="#password-authentication" title="Permanent link">&para;</a></h3>
<p>Password authentication uses the basic authorization header (username and password) to verify a user. With this method, the username and password must be sent with each request to a protected endpoint.</p>
<p>To use password authentication, you will first need to conform your Fluent model to <code>PasswordAuthenticatable</code>. </p>
<div class="codehilite"><pre><span></span><span class="kd">extension</span> <span class="nc">User</span><span class="p">:</span> <span class="n">PasswordAuthenticatable</span> <span class="p">{</span>
<span class="c1">/// See `PasswordAuthenticatable`.</span>
<span class="kd">static</span> <span class="kd">var</span> <span class="nv">usernameKey</span><span class="p">:</span> <span class="n">WritableKeyPath</span><span class="p">&lt;</span><span class="n">User</span><span class="p">,</span> <span class="nb">String</span><span class="p">&gt;</span> <span class="p">{</span>
<span class="k">return</span> <span class="err">\</span><span class="p">.</span><span class="n">email</span>
<span class="p">}</span>
<span class="c1">/// See `PasswordAuthenticatable`.</span>
<span class="kd">static</span> <span class="kd">var</span> <span class="nv">passwordKey</span><span class="p">:</span> <span class="n">WritableKeyPath</span><span class="p">&lt;</span><span class="n">User</span><span class="p">,</span> <span class="nb">String</span><span class="p">&gt;</span> <span class="p">{</span>
<span class="k">return</span> <span class="err">\</span><span class="p">.</span><span class="n">passwordHash</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
<p>Note that the <code>passwordKey</code> should point to the <em>hashed</em> password. Never store passwords in plaintext. </p>
<p>Once you have created an authenticatable model, the next step is to add middleware to your protected route.</p>
<div class="codehilite"><pre><span></span><span class="c1">// Use user model to create an authentication middleware</span>
<span class="kd">let</span> <span class="nv">password</span> <span class="p">=</span> <span class="n">User</span><span class="p">.</span><span class="n">basicAuthMiddleware</span><span class="p">(</span><span class="n">using</span><span class="p">:</span> <span class="n">BCryptDigest</span><span class="p">())</span>
<span class="c1">// Create a route closure wrapped by this middleware </span>
<span class="n">router</span><span class="p">.</span><span class="n">grouped</span><span class="p">(</span><span class="n">password</span><span class="p">).</span><span class="kr">get</span><span class="p">(</span><span class="s">&quot;hello&quot;</span><span class="p">)</span> <span class="p">{</span> <span class="n">req</span> <span class="k">in</span>
<span class="c1">///</span>
<span class="p">}</span>
</pre></div>
<p>Here we are using <code>BCryptDigest</code> as the <a href="https://api.vapor.codes/auth/latest/Authentication/Protocols/PasswordVerifier.html"><code>PasswordVerifier</code></a> since we are assuming the user's password is stored as a BCrypt hash. </p>
<p>Now, to fetch the authenticated user in the route closure, you can use <a href="https://api.vapor.codes/auth/latest/Authentication/Extensions/Request.html#/s:5Vapor7RequestC14AuthenticationE20requireAuthenticatedxxmKAD15AuthenticatableRzlF"><code>requireAuthenticated(_:)</code></a>. </p>
<div class="codehilite"><pre><span></span><span class="kd">let</span> <span class="nv">user</span> <span class="p">=</span> <span class="k">try</span> <span class="n">req</span><span class="p">.</span><span class="n">requireAuthenticated</span><span class="p">(</span><span class="n">User</span><span class="p">.</span><span class="kc">self</span><span class="p">)</span>
<span class="k">return</span> <span class="s">&quot;Hello, </span><span class="si">\(</span><span class="n">user</span><span class="p">.</span><span class="n">name</span><span class="si">)</span><span class="s">.&quot;</span>
</pre></div>
<p>The <code>requireAuthenticated</code> method will automatically throw an appropriate unauthorized error if the valid credentials were not supplied. Because of this, using <a href="https://api.vapor.codes/auth/latest/Authentication/Classes/GuardAuthenticationMiddleware.html"><code>GuardAuthenticationMiddleware</code></a> to protect the route from unauthenticated access is not required. </p>
<h3 id="token-authentication">Token Authentication<a class="headerlink" href="#token-authentication" title="Permanent link">&para;</a></h3>
<p>Token authentication uses the bearer authorization header (token) to lookup a token and its related user. With this method, the token must be sent with each request to a protected endpoint.</p>
<p>Unlike password authentication, token authentication relies on <em>two</em> Fluent models. One for the token and one for the user. The token model should be a <em>child</em> of the user model.</p>
<p>Here is an example of a very basic <code>User</code> and associated <code>UserToken</code>. </p>
<div class="codehilite"><pre><span></span><span class="kd">struct</span> <span class="nc">User</span><span class="p">:</span> <span class="n">Model</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nv">id</span><span class="p">:</span> <span class="nb">Int</span><span class="p">?</span>
<span class="kd">var</span> <span class="nv">name</span><span class="p">:</span> <span class="nb">String</span>
<span class="kd">var</span> <span class="nv">email</span><span class="p">:</span> <span class="nb">String</span>
<span class="kd">var</span> <span class="nv">passwordHash</span><span class="p">:</span> <span class="nb">String</span>
<span class="kd">var</span> <span class="nv">tokens</span><span class="p">:</span> <span class="n">Children</span><span class="p">&lt;</span><span class="n">User</span><span class="p">,</span> <span class="n">UserToken</span><span class="p">&gt;</span> <span class="p">{</span>
<span class="k">return</span> <span class="n">children</span><span class="p">(</span><span class="err">\</span><span class="p">.</span><span class="n">userID</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kd">struct</span> <span class="nc">UserToken</span><span class="p">:</span> <span class="n">Model</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nv">id</span><span class="p">:</span> <span class="nb">Int</span><span class="p">?</span>
<span class="kd">var</span> <span class="nv">string</span><span class="p">:</span> <span class="nb">String</span>
<span class="kd">var</span> <span class="nv">userID</span><span class="p">:</span> <span class="n">User</span><span class="p">.</span><span class="n">ID</span>
<span class="kd">var</span> <span class="nv">user</span><span class="p">:</span> <span class="n">Parent</span><span class="p">&lt;</span><span class="n">UserToken</span><span class="p">,</span> <span class="n">User</span><span class="p">&gt;</span> <span class="p">{</span>
<span class="k">return</span> <span class="n">parent</span><span class="p">(</span><span class="err">\</span><span class="p">.</span><span class="n">userID</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
<p>The first step to using token authentication is to conform your user and token models to their respective <code>Authenticatable</code> protocols.</p>
<div class="codehilite"><pre><span></span><span class="kd">extension</span> <span class="nc">UserToken</span><span class="p">:</span> <span class="n">Token</span> <span class="p">{</span>
<span class="c1">/// See `Token`.</span>
<span class="kd">typealias</span> <span class="n">UserType</span> <span class="p">=</span> <span class="n">User</span>
<span class="c1">/// See `Token`.</span>
<span class="kd">static</span> <span class="kd">var</span> <span class="nv">tokenKey</span><span class="p">:</span> <span class="n">WritableKeyPath</span><span class="p">&lt;</span><span class="n">UserToken</span><span class="p">,</span> <span class="nb">String</span><span class="p">&gt;</span> <span class="p">{</span>
<span class="k">return</span> <span class="err">\</span><span class="p">.</span><span class="n">string</span>
<span class="p">}</span>
<span class="c1">/// See `Token`.</span>
<span class="kd">static</span> <span class="kd">var</span> <span class="nv">userIDKey</span><span class="p">:</span> <span class="n">WritableKeyPath</span><span class="p">&lt;</span><span class="n">UserToken</span><span class="p">,</span> <span class="n">User</span><span class="p">.</span><span class="n">ID</span><span class="p">&gt;</span> <span class="p">{</span>
<span class="k">return</span> <span class="err">\</span><span class="p">.</span><span class="n">userID</span>
<span class="p">}</span>
<span class="p">}</span>
</pre></div>
<p>Once the token is conformed to <code>Token</code>, setting up the user model is easy.</p>
<div class="codehilite"><pre><span></span><span class="kd">extension</span> <span class="nc">User</span><span class="p">:</span> <span class="n">TokenAuthenticatable</span> <span class="p">{</span>
<span class="c1">/// See `TokenAuthenticatable`.</span>
<span class="kd">typealias</span> <span class="n">TokenType</span> <span class="p">=</span> <span class="n">UserToken</span>
<span class="p">}</span>
</pre></div>
<p>Once you have conformed your models, the next step is to add middleware to your protected route.</p>
<div class="codehilite"><pre><span></span><span class="c1">// Use user model to create an authentication middleware</span>
<span class="kd">let</span> <span class="nv">token</span> <span class="p">=</span> <span class="n">User</span><span class="p">.</span><span class="n">tokenAuthMiddleware</span><span class="p">()</span>
<span class="c1">// Create a route closure wrapped by this middleware </span>
<span class="n">router</span><span class="p">.</span><span class="n">grouped</span><span class="p">(</span><span class="n">token</span><span class="p">).</span><span class="kr">get</span><span class="p">(</span><span class="s">&quot;hello&quot;</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">//</span>
<span class="p">}</span>
</pre></div>
<p>Now, to fetch the authenticated user in the route closure, you can use <a href="https://api.vapor.codes/auth/latest/Authentication/Extensions/Request.html#/s:5Vapor7RequestC14AuthenticationE20requireAuthenticatedxxmKAD15AuthenticatableRzlF"><code>requireAuthenticated(_:)</code></a>. </p>
<div class="codehilite"><pre><span></span><span class="kd">let</span> <span class="nv">user</span> <span class="p">=</span> <span class="k">try</span> <span class="n">req</span><span class="p">.</span><span class="n">requireAuthenticated</span><span class="p">(</span><span class="n">User</span><span class="p">.</span><span class="kc">self</span><span class="p">)</span>
<span class="k">return</span> <span class="s">&quot;Hello, </span><span class="si">\(</span><span class="n">user</span><span class="p">.</span><span class="n">name</span><span class="si">)</span><span class="s">.&quot;</span>
</pre></div>
<p>The <code>requireAuthenticated</code> method will automatically throw an appropriate unauthorized error if the valid credentials were not supplied. Because of this, using <a href="https://api.vapor.codes/auth/latest/Authentication/Classes/GuardAuthenticationMiddleware.html"><code>GuardAuthenticationMiddleware</code></a> to protect the route from unauthenticated access is not required. </p>
<h2 id="__comments">Comments</h2>
<div id="disqus_thread"></div>
<script>
var disqus_config = function () {
this.page.url = "https://docs.vapor.codes/3.0/auth/api/";
this.page.identifier =
"auth/api/";
};
(function() {
var d = document, s = d.createElement("script");
s.src = "//vapor-docs.disqus.com/embed.js";
s.setAttribute("data-timestamp", +new Date());
(d.head || d.body).appendChild(s);
})();
</script>
</article>
</div>
</div>
</main>
<footer class="md-footer">
<div class="md-footer-nav">
<nav class="md-footer-nav__inner md-grid">
<a href="../getting-started/" title="Getting Started" class="md-flex md-footer-nav__link md-footer-nav__link--prev" rel="prev">
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-back md-footer-nav__button"></i>
</div>
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Previous
</span>
Getting Started
</span>
</div>
</a>
<a href="../web/" title="Sessions (Web)" class="md-flex md-footer-nav__link md-footer-nav__link--next" rel="next">
<div class="md-flex__cell md-flex__cell--stretch md-footer-nav__title">
<span class="md-flex__ellipsis">
<span class="md-footer-nav__direction">
Next
</span>
Sessions (Web)
</span>
</div>
<div class="md-flex__cell md-flex__cell--shrink">
<i class="md-icon md-icon--arrow-forward md-footer-nav__button"></i>
</div>
</a>
</nav>
</div>
<div class="md-footer-meta md-typeset">
<div class="md-footer-meta__inner md-grid">
<div class="md-footer-copyright">
<div class="md-footer-copyright__highlight">
Copyright &copy; 2018 Qutheory, LLC
</div>
powered by
<a href="https://www.mkdocs.org">MkDocs</a>
and
<a href="https://squidfunk.github.io/mkdocs-material/">
Material for MkDocs</a>
</div>
<div class="md-footer-social">
<link rel="stylesheet" href="../../assets/fonts/font-awesome.css">
<a href="https://twitter.com/@codevapor" class="md-footer-social__link fa fa-twitter"></a>
<a href="http://vapor.team/" class="md-footer-social__link fa fa-slack"></a>
<a href="https://github.com/vapor" class="md-footer-social__link fa fa-github"></a>
</div>
</div>
</div>
</footer>
</div>
<script src="../../assets/javascripts/application.5e60981f.js"></script>
<script>app.initialize({version:"1.0.4",url:{base:"../.."}})</script>
<script>!function(e,a,t,n,o,c,i){e.GoogleAnalyticsObject=o,e.ga=e.ga||function(){(e.ga.q=e.ga.q||[]).push(arguments)},e.ga.l=1*new Date,c=a.createElement(t),i=a.getElementsByTagName(t)[0],c.async=1,c.src="https://www.google-analytics.com/analytics.js",i.parentNode.insertBefore(c,i)}(window,document,"script",0,"ga"),ga("create","UA-76177358-4","auto"),ga("set","anonymizeIp",!0),ga("send","pageview");var links=document.getElementsByTagName("a");if(Array.prototype.map.call(links,function(e){e.host!=document.location.host&&e.addEventListener("click",function(){var a=e.getAttribute("data-md-action")||"follow";ga("send","event","outbound",a,e.href)})}),document.forms.search){var query=document.forms.search.query;query.addEventListener("blur",function(){if(this.value){var e=document.location.pathname;ga("send","pageview",e+"?q="+this.value)}})}</script>
</body>
</html>