Skip to content

Commit fcb5003

Browse files
trodriguestimdorr
authored andcommitted
Add example for async auth with querystring params (#3248)
Simple workflow that uses querystring parameters to determine if a user can look at a page or not. Parameters can come from a form submission, or from an url with those parameters in.
1 parent db083ae commit fcb5003

File tree

3 files changed

+113
-0
lines changed

3 files changed

+113
-0
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import React, { createClass, PropTypes } from 'react'
2+
import { render } from 'react-dom'
3+
import { Router, Route, IndexRoute, browserHistory, Link } from 'react-router'
4+
5+
function App(props) {
6+
return (
7+
<div>
8+
{props.children}
9+
</div>
10+
)
11+
}
12+
13+
const Form = createClass({
14+
contextTypes: {
15+
router: PropTypes.object.isRequired
16+
},
17+
18+
getInitialState() {
19+
return {
20+
value: ''
21+
}
22+
},
23+
24+
submitAction(event) {
25+
event.preventDefault()
26+
this.context.router.push({
27+
pathname: '/page',
28+
query: {
29+
qsparam: this.state.value
30+
}
31+
})
32+
},
33+
34+
handleChange(event) {
35+
this.setState({ value: event.target.value })
36+
},
37+
38+
render() {
39+
return (
40+
<form onSubmit={this.submitAction}>
41+
<p>Token is <em>pancakes</em></p>
42+
<input type="text" value={this.state.value} onChange={this.handleChange} />
43+
<button type="submit">Submit the thing</button>
44+
<p><Link to="/page?qsparam=pancakes">Or authenticate via URL</Link></p>
45+
<p><Link to="/page?qsparam=bacon">Or try failing to authenticate via URL</Link></p>
46+
</form>
47+
)
48+
}
49+
})
50+
51+
function Page() {
52+
return <h1>Hey I see you are authenticated.</h1>
53+
}
54+
55+
function ErrorPage() {
56+
return <h1>Oh no! your auth failed!</h1>
57+
}
58+
59+
function requireCredentials(nextState, replace, next) {
60+
const query = nextState.location.query
61+
if (query.qsparam) {
62+
serverAuth(query.qsparam)
63+
.then(
64+
() => next(),
65+
() => {
66+
replace('/error')
67+
next()
68+
}
69+
)
70+
} else {
71+
replace('/error')
72+
next()
73+
}
74+
}
75+
76+
function serverAuth(authToken) {
77+
return new Promise((resolve, reject) => {
78+
// That server is gonna take a while
79+
setTimeout(() => {
80+
if(authToken === 'pancakes') {
81+
resolve('authenticated')
82+
} else {
83+
reject('nope')
84+
}
85+
}, 200)
86+
})
87+
}
88+
89+
render((
90+
<Router history={browserHistory}>
91+
<Route path="/" component={App}>
92+
<IndexRoute component={Form} />
93+
<Route path="page" component={Page} onEnter={requireCredentials}/>
94+
<Route path="error" component={ErrorPage}/>
95+
</Route>
96+
</Router>
97+
), document.getElementById('example'))
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<base href="/auth-flow-async-with-query-params"/>
5+
<meta charset="utf-8">
6+
<title>Authentication with query parameters</title>
7+
<link rel="stylesheet" href="/global.css"/>
8+
</head>
9+
<body>
10+
<h1 class="breadcrumbs"><a href="/">React Router Examples</a> / Async Auth with Query Parameters</h1>
11+
<div id="example"/>
12+
<script src="/__build__/shared.js"></script>
13+
<script src="/__build__/auth-flow-async-with-query-params.js"></script>
14+
</body>
15+
</html>

examples/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ <h1>React Router Examples</h1>
88
<li><a href="animations">Animations</a></li>
99
<li><a href="auth-flow">Auth Flow</a></li>
1010
<li><a href="auth-with-shared-root">Auth with Shared Root</a></li>
11+
<li><a href="auth-flow-async-with-query-params">Async Auth with Query Parameters</a></li>
1112
<li><a href="breadcrumbs">Breadcrumbs</a></li>
1213
<li><a href="confirming-navigation">Confirming Navigation</a></li>
1314
<li><a href="dynamic-segments">Dynamic Segments</a></li>

0 commit comments

Comments
 (0)