Skip to content

Commit 74001a8

Browse files
committed
Adding initial app
1 parent 59c6bc9 commit 74001a8

5 files changed

+215
-1
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,13 @@ local.properties
4242
*.iml
4343
/android/
4444

45+
# iOS
46+
/ios/
47+
4548
# Node
4649
node_modules
4750
*.log
4851
.nvm
4952

5053
# OS X
51-
.DS_Store
54+
.DS_Store
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
2+
# Adding Authentication to Your React Native App Using JSON Web Tokens
3+
You have many, many choices out there that can help you get user authentication into your React Native application. The advantages to using JWTs over other, more traditional authentication methods are many. The app will be stateless, and we don’t have to worry about issues like load balancing with sessions or cookie problems. We can authenticate users across multiple domains, integrate easily with other authentication services, and reduce the load on our servers. Sounds great, right?
4+
5+
Here’s the thing. We, as developers, don’t need more complication in our apps, in our projects, or in our lives. User authentication is always a pain. _Someone_ always wants more SSO options. _Someone_ always wants better security. _Someone_ always finds vulnerabilities. And yes, there are vulnerabilities in any system. But mitigating the _chances_ of problems of all kinds - technical problems, server problems, cookie problems, hacking problems - is what we’re all trying to do all the time, isn’t it? An easy-to-implement token based authentication system provides just that. If we’re building a React Native app, we are probably intending to cover multiple platforms with minimal changes. Let’s take it one step further and have the same stateless authentication procedures for all versions of our app, too.
6+
7+
## What We’re Building
8+
This tutorial will demonstrate how to authenticate our users to a React Native app using [JSON Web Tokens][1]. We’ll go ahead and use [this Auth0 sample API][2] as our app’s backend. We’ll be building a little app that deals in the ever-ubiquitous Chuck Norris quotes (Who doesn’t love a good Chuck Norris joke?), and we’ll be authenticating our users with JWTs, which will be the primary purpose of this tutorial.
9+
10+
OK, let’s get started with our setup.
11+
12+
## Setup and Installations
13+
First, let’s set up a React Native app. We can start with a brand new one, for the purposes of this tutorial, so just spin up a new project. If you’re not familiar with React Native, the [documentation][3] has an excellent Getting Started page to help you get that set up. You’ll also want to go ahead and clone [this Auth0 sample API][4] backend, which employs Node.js, and get it running locally.
14+
15+
## Integrating With Our Backend
16+
OK, so we have our backend downloaded and running locally. Let’s hit the URL associated with it - by default `http://localhost:3001/api/random-quote`. This will reassure us that our backend that provides fun-filled Chuck Norris quotes is indeed working. OK, and here we go:
17+
18+
![Test of the JWT API Sample][image-1]
19+
20+
Next up, let’s take a look at our starter React Native app, which, if following the tutorial linked above, should look something like this:
21+
22+
23+
Paste of original React Native getting started app
24+
25+
So let’s now modify this to deal with our API, before we add in our authentication. In this case, our needs are rather simple. We just need to send our request to the above URL, and then collect the returned quote and display it.
26+
27+
[1]: https://jwt.io/introduction/ "What are JSON Web Tokens?"
28+
[2]: https://github.com/auth0-blog/nodejs-jwt-authentication-sample "Auth0 JWT Sample Authentication API"
29+
[3]: https://facebook.github.io/react-native/docs/getting-started.html#content "React Native - Getting Started"
30+
[4]: https://github.com/auth0-blog/nodejs-jwt-authentication-sample "Auth0 JWT Sample Authentication API"
31+
32+
[image-1]: http://i.imgur.com/7DJIdip.png "API Sample Test"

docs/reactnative-jwts_api-test.png

21.1 KB
Loading

index.ios.js

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
var ReactNative = require('react-native');
2+
var React = require('react');
3+
4+
var {
5+
AppRegistry,
6+
AsyncStorage,
7+
StyleSheet,
8+
Text,
9+
View,
10+
TouchableHighlight,
11+
AlertIOS,
12+
} = ReactNative;
13+
14+
var demo_jwt = null;
15+
16+
var AwesomeProject = React.createClass({
17+
componentDidMount() {
18+
demo_jwt = this._loadInitialState().done();
19+
},
20+
21+
async _loadInitialState() {
22+
var value = await AsyncStorage.getItem('demo_jwt');
23+
if (value !== null){
24+
this.setState({'demo_jwt': value});
25+
return(value);
26+
} else {
27+
return(null);
28+
}
29+
},
30+
31+
_getQuote: function() {
32+
fetch("http://localhost:3001/api/random-quote", {
33+
method: "GET",
34+
})
35+
.then((response) => response)
36+
.then((responseData) => {
37+
AlertIOS.alert(
38+
"Chuck Norris Quote:",
39+
responseData._bodyText)
40+
})
41+
.done();
42+
},
43+
44+
_getProtectedQuote: function() {
45+
fetch("http://localhost:3001/protected/random-quote", {
46+
method: "GET",
47+
Authorization: 'Bearer {jwt}'
48+
})
49+
.then((response) => response)
50+
.then((responseData) => {
51+
AlertIOS.alert(
52+
"Chuck Norris Quote:",
53+
responseData._bodyText)
54+
})
55+
.done();
56+
},
57+
58+
_userSignup: function() {
59+
fetch("http://localhost:3001/users", {
60+
method: "POST",
61+
headers: {
62+
'Accept': 'application/json',
63+
'Content-Type': 'application/json'
64+
},
65+
body: JSON.stringify({
66+
username: "testuser3",
67+
password: "testpassword3",
68+
extra: "He's a test user"
69+
})
70+
})
71+
.then((response) => response)
72+
.then((responseData) => {
73+
AlertIOS.alert(
74+
"Successfully Signed Up! (Token):",
75+
responseData.id_token)
76+
})
77+
.done();
78+
AsyncStorage.setItem('demo_jwt', responseData.id_token);
79+
},
80+
81+
_userLogin: function() {
82+
fetch("http://localhost:3001/users", {
83+
method: "POST",
84+
headers: {
85+
'Accept': 'application/json',
86+
'Content-Type': 'application/json'
87+
},
88+
body: JSON.stringify({
89+
username: "testuser2",
90+
password: "testpassword2",
91+
})
92+
})
93+
.then((response) => response.json())
94+
.then((responseData) => {
95+
AlertIOS.alert(
96+
"POST Response",
97+
"Response Body -> " + JSON.stringify(responseData.body)
98+
)
99+
})
100+
.done();
101+
},
102+
103+
render: function() {
104+
return (
105+
<View style={styles.container}>
106+
<View style={styles.row}>
107+
<Text style={styles.title}>Click below to get a Chuck Norris Quote!</Text>
108+
</View>
109+
110+
<View style={styles.row}>
111+
<TouchableHighlight onPress={this._getQuote} style={styles.button}>
112+
<Text>Get a Chuck Norris Quote!</Text>
113+
</TouchableHighlight>
114+
</View>
115+
<View style={styles.row}>
116+
<Text style={styles.body}>Signup (or Login) to be even more satisfied with your Chuck Norris quotes!</Text>
117+
</View>
118+
<View style={styles.row}>
119+
<TouchableHighlight onPress={this._userSignup} style={styles.button}>
120+
<Text>Signup</Text>
121+
</TouchableHighlight>
122+
<TouchableHighlight onPress={this._userLogin} style={styles.button}>
123+
<Text>Login</Text>
124+
</TouchableHighlight>
125+
</View>
126+
<View style={styles.row}>
127+
<TouchableHighlight onPress={this._getProtectedQuote} style={styles.button}>
128+
<Text>Get More Satisfying Quotes!</Text>
129+
</TouchableHighlight>
130+
</View>
131+
</View>
132+
);
133+
},
134+
});
135+
136+
var styles = StyleSheet.create({
137+
container: {
138+
padding:20,
139+
flex: 1,
140+
},
141+
row: {
142+
flexDirection: 'row',
143+
margin: 10,
144+
flexWrap: 'wrap',
145+
justifyContent: 'center',
146+
},
147+
button: {
148+
backgroundColor: '#eeeeee',
149+
padding: 10,
150+
marginRight: 5,
151+
marginLeft: 5,
152+
},
153+
title: {
154+
justifyContent: 'center',
155+
fontSize: 16,
156+
fontWeight: 'bold',
157+
},
158+
body: {
159+
justifyContent: 'center',
160+
fontSize: 12,
161+
flexWrap: 'wrap',
162+
flex: 1,
163+
}
164+
});
165+
166+
AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);
167+

package.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"name": "ReactNativeAndJWTs",
3+
"version": "0.0.1",
4+
"private": true,
5+
"scripts": {
6+
"start": "node node_modules/react-native/local-cli/cli.js start"
7+
},
8+
"dependencies": {
9+
"react": "^0.14.8",
10+
"react-native": "^0.25.1"
11+
}
12+
}

0 commit comments

Comments
 (0)