-
Notifications
You must be signed in to change notification settings - Fork 29.9k
/
Auth.tsx
104 lines (91 loc) · 2.51 KB
/
Auth.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import * as React from 'react';
import {
BrowserRouter as Router,
RouteComponentProps,
RouteProps,
Route,
Link,
Redirect,
withRouter
} from 'react-router-dom';
import { StaticContext } from 'react-router';
////////////////////////////////////////////////////////////
// 1. Click the public page
// 2. Click the protected page
// 3. Log in
// 4. Click the back button, note the URL each time
const AuthExample = () => (
<Router>
<div>
<AuthButton/>
<ul>
<li><Link to="/public">Public Page</Link></li>
<li><Link to="/protected">Protected Page</Link></li>
</ul>
<Route path="/public" component={Public}/>
<Route path="/login" component={Login}/>
<PrivateRoute path="/protected" component={Protected}/>
</div>
</Router>
);
const fakeAuth = {
isAuthenticated: false,
authenticate(this: any, cb: () => void) {
this.isAuthenticated = true;
setTimeout(cb, 100); // fake async
},
signout(this: any, cb: () => void) {
this.isAuthenticated = false;
setTimeout(cb, 100);
}
};
const AuthButton = withRouter(({ history }) => (
fakeAuth.isAuthenticated ? (
<p>
Welcome! <button onClick={() => {
fakeAuth.signout(() => history.push('/'));
}}>Sign out</button>
</p>
) : (
<p>You are not logged in.</p>
)
));
const PrivateRoute: React.SFC<RouteProps> = ({ component, ...rest }) => (
<Route {...rest} render={props => (
fakeAuth.isAuthenticated ? React.createElement(component! as React.SFC<any>, props) : (
<Redirect to={{
pathname: '/login',
state: { from: props.location }
}}/>
)
)}/>
);
const Public: React.SFC<RouteComponentProps> = () => <h3>Public</h3>;
const Protected: React.SFC<RouteComponentProps> = () => <h3>Protected</h3>;
type Props = RouteComponentProps<{}, StaticContext, { from: { pathname: string; }; }>;
class Login extends React.Component<Props, {redirectToReferrer: boolean}> {
state = {
redirectToReferrer: false
};
login = () => {
fakeAuth.authenticate(() => {
this.setState({ redirectToReferrer: true });
});
}
render() {
const { from } = this.props.location.state || { from: { pathname: '/' } };
const { redirectToReferrer } = this.state;
if (redirectToReferrer) {
return (
<Redirect to={from}/>
);
}
return (
<div>
<p>You must log in to view the page at {from.pathname}</p>
<button onClick={this.login}>Log in</button>
</div>
);
}
}
export default AuthExample;