Authentication v1 - cheehongw/functional_expressionism GitHub Wiki
The authentication system is done using Firebase Authentication. Although Google has done a great job in abstracting most of the authentication work, there are a lot of issues to solve to implement an authentication system.
These are the things we have accomplished in the first version of authentication:
- Firebase: Set up the authentication system and removing the security rules temporarily on Firebase to experiment a few of our ideas. The default configuration of Firebase does not allow any read or write request if the request is not authenticated.
- Sign-in & Sign-up: Create a simple form using React to test the Firebase key. Unfortunately, due to a problem in the code (as shown below), it burned a lot of time and hence we are only successful in signing up an user and letting the user sign in successfully. There are no restrictions in the e-mail or password provided by the user.
- Routing: Primitive routing between sign in and sign up.
The problem that we ran into (due to the somewhat naive code) is that the state updates may be asynchronous, meaning we should not rely on their values for calculating the next state. So we have a form for signing up and its supporting code (adapted from the React JS workshop code):
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const signUpWithEmailAndPassword = () => {
firebase.auth().createUserWithEmailAndPassword(email, password)
.then((userCredential) => {...}
}
.catch((error) => {
var errorCode = error.code;
var errorMessage = error.message;
}
<form onSubmit={signUpWithEmailAndPassword}>
<input type="text" placeholder="Enter Email" name="email" onChange={setEmail}>
<input type="password" placeholder="Enter Password" name="psw" onChange={setPassword}>
<button type="submit" class="signup">Sign Up</button>
</form>
But this unfortunately always return an error The email is badly formatted
by Firebase. This is because when we call
firebase.auth().createUserWithEmailAndPassword(email, password)
the email state might not update yet, hence we are essentially calling
firebase.auth().createUserWithEmailAndPassword("", password)
thus create the problem above. Our solution to handle this to allow the email to update is to use the React hook useEffect
to wait for the email and password states to update before executing the createUserWithEmailAndPassword
function
- Allow users to sign in using Google account
- Block the creation of accounts with weak password and existing email address
- Allow every user to have an avatar and a unique username
- Send a verification email to the registered email, block any sign in attempt from any account with non-verified email address
- Implement a forget password system
- Sign in persistance (Remember me option)
- Allow users to change their username and avatar image
- Allow users to delete their account and change their password after signed in
- Create a profile page to display the user's username and avatar image
- For sign in attempts from non-verified users, send a verification email again to let them verified
- Redirect to the main page when the user is done signing in
- Redirect to the sign in page when the user is done signing up
- Block access to any page which requires the user to sign in to access
- Create a context of the current user for the other pages in the web app
- Hide the API key of Firebase to avoid possible exploitation
- Revert the changes to the rules of Firebase to only allow read and write to authenticated request
- UI changes: apply Material UI to form and displaying errors (non-verified email address, invalid email/password)