Skip to content

Commit 8d18ab1

Browse files
committed
Re-adding iOS directory + new changes
1 parent 74001a8 commit 8d18ab1

File tree

967 files changed

+11214
-73
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

967 files changed

+11214
-73
lines changed

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ local.properties
4343
/android/
4444

4545
# iOS
46-
/ios/
46+
4747

4848
# Node
4949
node_modules
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
1+
[https://www.npmjs.com/package/react-native-simple-router][1]
2+
3+
[https://www.npmjs.com/package/react-native-form-generator][2]
4+
15

26
# Adding Authentication to Your React Native App Using JSON Web Tokens
37
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?
48

59
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.
610

711
## 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.
12+
This tutorial will demonstrate how to authenticate our users to a React Native app using [JSON Web Tokens][3]. We’ll go ahead and use [this Auth0 sample API][4] 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.
913

1014
OK, let’s get started with our setup.
1115

1216
## 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.
17+
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][5] 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][6] backend, which employs Node.js, and get it running locally.
1418

1519
## Integrating With Our Backend
1620
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:
@@ -19,14 +23,16 @@ OK, so we have our backend downloaded and running locally. Let’s hit the URL
1923

2024
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:
2125

22-
26+
2327
Paste of original React Native getting started app
2428

2529
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.
2630

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"
31+
[1]: https://www.npmjs.com/package/react-native-simple-router
32+
[2]: https://www.npmjs.com/package/react-native-form-generator
33+
[3]: https://jwt.io/introduction/ "What are JSON Web Tokens?"
3034
[4]: https://github.com/auth0-blog/nodejs-jwt-authentication-sample "Auth0 JWT Sample Authentication API"
35+
[5]: https://facebook.github.io/react-native/docs/getting-started.html#content "React Native - Getting Started"
36+
[6]: https://github.com/auth0-blog/nodejs-jwt-authentication-sample "Auth0 JWT Sample Authentication API"
3137

3238
[image-1]: http://i.imgur.com/7DJIdip.png "API Sample Test"

index.android.js

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/**
2+
* Sample React Native App
3+
* https://github.com/facebook/react-native
4+
*/
5+
6+
import React, { Component } from 'react';
7+
import {
8+
AppRegistry,
9+
StyleSheet,
10+
Text,
11+
View
12+
} from 'react-native';
13+
14+
class AwesomeProject extends Component {
15+
render() {
16+
return (
17+
<View style={styles.container}>
18+
<Text style={styles.welcome}>
19+
Welcome to React Native!
20+
</Text>
21+
<Text style={styles.instructions}>
22+
To get started, edit index.android.js
23+
</Text>
24+
<Text style={styles.instructions}>
25+
Shake or press menu button for dev menu
26+
</Text>
27+
</View>
28+
);
29+
}
30+
}
31+
32+
const styles = StyleSheet.create({
33+
container: {
34+
flex: 1,
35+
justifyContent: 'center',
36+
alignItems: 'center',
37+
backgroundColor: '#F5FCFF',
38+
},
39+
welcome: {
40+
fontSize: 20,
41+
textAlign: 'center',
42+
margin: 10,
43+
},
44+
instructions: {
45+
textAlign: 'center',
46+
color: '#333333',
47+
marginBottom: 5,
48+
},
49+
});
50+
51+
AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);

index.ios.js

+108-65
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
var ReactNative = require('react-native');
21
var React = require('react');
2+
var ReactNative = require('react-native');
3+
var t = require('tcomb-form-native');
34

45
var {
56
AppRegistry,
@@ -11,100 +12,120 @@ var {
1112
AlertIOS,
1213
} = ReactNative;
1314

14-
var demo_jwt = null;
15+
var STORAGE_KEY = 'id_token';
16+
17+
var Form = t.form.Form;
18+
19+
var Person = t.struct({
20+
username: t.String,
21+
password: t.String
22+
});
23+
24+
var options = {}; // optional rendering options (see documentation)
1525

1626
var AwesomeProject = React.createClass({
17-
componentDidMount() {
18-
demo_jwt = this._loadInitialState().done();
19-
},
2027

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+
onPress: function () {
29+
// call getValue() to get the values of the form
30+
var value = this.refs.form.getValue();
31+
if (value) { // if validation fails, value will be null
32+
this._userSignup(value);
33+
}
34+
},
35+
36+
async _onValueChange(item, selectedValue) {
37+
try {
38+
await AsyncStorage.setItem(item, selectedValue);
39+
} catch (error) {
40+
console.log('AsyncStorage error: ' + error.message);
2841
}
2942
},
3043

3144
_getQuote: function() {
3245
fetch("http://localhost:3001/api/random-quote", {
3346
method: "GET",
3447
})
35-
.then((response) => response)
36-
.then((responseData) => {
37-
AlertIOS.alert(
38-
"Chuck Norris Quote:",
39-
responseData._bodyText)
40-
})
41-
.done();
48+
.then(response => response.text())
49+
.then(quote => {
50+
AlertIOS.alert("Chuck Norris Quote:", quote)
51+
});
4252
},
4353

44-
_getProtectedQuote: function() {
45-
fetch("http://localhost:3001/protected/random-quote", {
54+
async _getProtectedQuote() {
55+
var DEMO_TOKEN = await AsyncStorage.getItem(STORAGE_KEY);
56+
console.log("DEMO_TOKEN: " + DEMO_TOKEN);
57+
fetch("http://localhost:3001/api/protected/random-quote", {
4658
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",
6159
headers: {
6260
'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-
})
61+
'Content-Type': 'application/json',
62+
'Authorization': 'Bearer ' + DEMO_TOKEN
63+
}
7064
})
71-
.then((response) => response)
72-
.then((responseData) => {
65+
.then((response) => response.text())
66+
.then((quote) => {
7367
AlertIOS.alert(
74-
"Successfully Signed Up! (Token):",
75-
responseData.id_token)
68+
"Chuck Norris Quote:", quote)
7669
})
7770
.done();
78-
AsyncStorage.setItem('demo_jwt', responseData.id_token);
7971
},
8072

81-
_userLogin: function() {
82-
fetch("http://localhost:3001/users", {
73+
_userSignup: function() {
74+
var value = this.refs.form.getValue();
75+
if (value) { // if validation fails, value will be null
76+
fetch("http://localhost:3001/users", {
8377
method: "POST",
8478
headers: {
8579
'Accept': 'application/json',
8680
'Content-Type': 'application/json'
8781
},
8882
body: JSON.stringify({
89-
username: "testuser2",
90-
password: "testpassword2",
83+
username: value.username,
84+
password: value.password,
9185
})
9286
})
9387
.then((response) => response.json())
9488
.then((responseData) => {
89+
this._onValueChange(STORAGE_KEY, JSON.stringify(responseData.id_token)),
9590
AlertIOS.alert(
9691
"POST Response",
97-
"Response Body -> " + JSON.stringify(responseData.body)
92+
"Response Body -> " + JSON.stringify(responseData.id_token)
9893
)
9994
})
10095
.done();
96+
}
97+
},
98+
_userLogin: function() {
99+
var value = this.refs.form.getValue();
100+
if (value) { // if validation fails, value will be null
101+
fetch("http://localhost:3001/sessions/create", {
102+
method: "POST",
103+
headers: {
104+
'Accept': 'application/json',
105+
'Content-Type': 'application/json'
106+
},
107+
body: JSON.stringify({
108+
username: value.username,
109+
password: value.password,
110+
})
111+
})
112+
.then((response) => response.json())
113+
.then((responseData) => {
114+
AlertIOS.alert(
115+
"POST Response",
116+
"Response Body -> " + JSON.stringify(responseData.id_token)
117+
),
118+
this._onValueChange(STORAGE_KEY, JSON.stringify(responseData.id_token))
119+
})
120+
.done();
121+
}
101122
},
102123

103124
render: function() {
104125
return (
105126
<View style={styles.container}>
106127
<View style={styles.row}>
107-
<Text style={styles.title}>Click below to get a Chuck Norris Quote!</Text>
128+
<Text style={styles.title}>Signup/Login below for Chuck Norris Quotes!</Text>
108129
</View>
109130

110131
<View style={styles.row}>
@@ -113,14 +134,22 @@ var AwesomeProject = React.createClass({
113134
</TouchableHighlight>
114135
</View>
115136
<View style={styles.row}>
116-
<Text style={styles.body}>Signup (or Login) to be even more satisfied with your Chuck Norris quotes!</Text>
137+
<Text style={styles.title}>Signup/Login</Text>
117138
</View>
118-
<View style={styles.row}>
119-
<TouchableHighlight onPress={this._userSignup} style={styles.button}>
120-
<Text>Signup</Text>
139+
<View style={styles.row}>
140+
<Form
141+
ref="form"
142+
type={Person}
143+
options={options}
144+
style={styles.form}
145+
/>
146+
</View>
147+
<View style={styles.row}>
148+
<TouchableHighlight style={styles.button} onPress={this._userSignup} underlayColor='#99d9f4'>
149+
<Text style={styles.buttonText}>Signup</Text>
121150
</TouchableHighlight>
122-
<TouchableHighlight onPress={this._userLogin} style={styles.button}>
123-
<Text>Login</Text>
151+
<TouchableHighlight style={styles.button} onPress={this._userLogin} underlayColor='#99d9f4'>
152+
<Text style={styles.buttonText}>Login</Text>
124153
</TouchableHighlight>
125154
</View>
126155
<View style={styles.row}>
@@ -130,7 +159,7 @@ var AwesomeProject = React.createClass({
130159
</View>
131160
</View>
132161
);
133-
},
162+
}
134163
});
135164

136165
var styles = StyleSheet.create({
@@ -144,11 +173,25 @@ var styles = StyleSheet.create({
144173
flexWrap: 'wrap',
145174
justifyContent: 'center',
146175
},
176+
buttonText: {
177+
fontSize: 16,
178+
color: 'white',
179+
alignSelf: 'center'
180+
},
147181
button: {
148-
backgroundColor: '#eeeeee',
149-
padding: 10,
150-
marginRight: 5,
151-
marginLeft: 5,
182+
height: 36,
183+
backgroundColor: '#B7B7B7',
184+
borderColor: '#000000',
185+
borderWidth: 1,
186+
borderRadius: 8,
187+
marginBottom: 10,
188+
marginLeft: 10,
189+
marginRight: 10,
190+
alignSelf: 'stretch',
191+
justifyContent: 'center'
192+
},
193+
form: {
194+
width:200
152195
},
153196
title: {
154197
justifyContent: 'center',
@@ -162,6 +205,6 @@ var styles = StyleSheet.create({
162205
flex: 1,
163206
}
164207
});
165-
208+
166209
AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);
167210

0 commit comments

Comments
 (0)