I am trying to build a full stack web application using React JS and Spring. I have created an API for Login.
#PostMapping("/users/login")
public Status loginUser(#Valid #RequestBody PortalUser user) {
List<PortalUser> users = userRepository.findAll();
for (PortalUser other : users) {
if (other.equals(user)) {
return Status.SUCCESS;
}
}
return Status.FAILURE;
}
This API checks if user has entered correct login credentials or not. If yes, then it returns Enum as "SUCCESS" and if not then it returns Enum as "FAILURE".
The web API works fine on Postman. I now want to call the same from my frontend but I am unable to do so. Could anyone help me out with the same?
const user_base_url = "http://localhost:8080/users";
class CustomerService{
authenticateUser(user) {
return axios.post(user_base_url+ '/login', user);
}
}
I have created this function to call the API using axios.
validateUser = () => {
let user = {
username: this.state.email,
password: this.state.password
};
authenticateUser(user);
I am unable to proceed after this.
I basically want to authenticate the User when the login button (the Validate User function is called) is pressed.
Any help would be highly appreciated.
You can do something like this
const user_base_url = "http://localhost:8080/users";
class CustomerService{
authenticateUser(user) {
return axios.post(user_base_url+ '/login', user)
.then((res)=>{
if(res.data === 'SUCCESS') {
//user logged in
} else if(res.data === 'FAILURE') {
//login failed
}})
.catch(err) {
console.error(err)
}
}
}
Related
I currently have a file for authentication called AuthContext.js and a seperate file called Login.js for my login page. Firebase is only imported into the AuthContext file and it currently works, the method appears as follows
function signup(email, password) {
return auth.createUserWithEmailAndPassword(email, password);
}
And the method is called in the Login file inside of an async function.
async function handleSubmit(e) {
e.preventDefault();
if (passwordRef.current.value !== passwordConfirmRef.current.value) {
return setError("Passwords do not match");
}
try {
setError("");
setLoading(true);
await signup(emailRef.current.value, passwordRef.current.value);
navigate("/");
} catch (err) {
setError("Failed to create an account");
}
setLoading(false);
}
I am now attempting to integrate email authentication into the function. I would like to get it to where, if an account remains unverified for a elongated duration then it will delete the account, but I think that Is likely in the Firebase settings.
I found this article on geeksforgeeks that suggested calling the method in the following manner:
const signup = ()=>{
auth.createUserWithEmailAndPassword(email , password)
.then((userCredential)=>{
// send verification mail.
userCredential.user.sendEmailVerification();
auth.signOut();
alert("Email sent");
})
.catch(alert);
}
However, when I attempted to return this function in the form
function signup(email, password) {
return auth.createUserWithEmailAndPassword(email, password).then(
(userCredentials) => {
userCredentials.user.sendEmailVerification();
auth.signOut();
auth.alert("Please verify your email address before logging in.");
}
);
}
It does not work properly, and I get error messages every time I try to sign up a new account. How do I properly implement this to where the promise returns properly and displays the correct message? Is there a way for me to link them to the /login page with an alert already on it that says "Please verify your email address before logging in."? Thanks in advance for any help!
I want to implement role based authentication in my app.
After researching for a while I found a simple solution - to pass role to signIn function
signIn('email', { email, role: 'user' });
Then I can unpack it from req's body
import NextAuth from 'next-auth'
export default async function auth(req, res) {
return NextAuth(req, res, {
// providers, adapters, etc.
callbacks: {
signIn: async ({ user }) => {
const { body: { role } } = req;
if (role) {
user.role = role;
}
return true;
},
session: async ({ user, session }) => {
session.user = {...session.user, ...user };
return session
}
}
}
});
Or so I thought. Magic link sign in flow has two steps: sending email and confirming it.
The role I provide to signIn function is only available during the first step and saving user to users collection only happens after user confirms email, so when user confirms email there's no role.
I tried storing role in cookies
if (role) res.setHeader('Set-Cookie', 'user-role=' + role + ';Max-Age=600');
But cookies get overriden after I confirm email and the role is lost.
I don't want to create additional collections and/or records in my database.
How can I preserve role inside signIn callback without storing it in a separate database collection? Maybe there's some other solution you can think of?
I'm posting here hoping one of you could help me. I have a very little of programming knowledge and I'm being asked to put together a simple e-commerce website in Angular and ASP.NET Core MVC 3. So the following code is supposed to not log the user out if he/she is logged in but tries to access the admin's page through url. This is a bit of code that my professor told us to use but for some reason it doesn't work for me. He's using an older version of Angular, so for example, where he uses .map(), I have to use .pipe(map()) and where he had response.json().role I did just response.role. My IDE is showing me the following error in the client side login method around response.authenticated and response.role
Property 'authenticated' (or 'role') does not exist on type 'boolean'.
I suspect the problem is with returning multiple arguments on the client side login method or it's caused by the .pipe(map()). I'm clueless here, to be honest. I'd appreciate any guidance
login:
login(): Observable<any> {
this.authenticated = false;
return this.repo.login(this.name, this.password).pipe(
map(response => {
if (response.authenticated == 'true') {
this.authenticated = true;
this.password = null;
this.role = response.role;
if (this.role == 'Administrator') {
this.router.navigateByUrl("/admin/overview");
this.admin = true;
}
else {
this.router.navigateByUrl("/");
}
}
return this.authenticated;
}),
catchError(e => {
this.authenticated = false;
return of(false);
})
);
}
server side login:
[HttpPost("/api/account/login")]
public async Task<IActionResult> Login([FromBody] LoginViewModel creds) {
if (ModelState.IsValid && await DoLogin(creds)) {
IdentityUser user = await userManager.FindByNameAsync(creds.Name);
if (await userManager.IsInRoleAsync(user, "Administrator"))
return Ok(new { authenticated = "true", role = "Administrator"} );
else
return Ok( new { authenticated = "true", role = "NoAdministrator" });
}
return BadRequest();
}
The error is very clear. response is not an object to access its members (authenticate).
This returns boolean:
this.repo.login(this.name, this.password);
Change your condition to:
response == 'true'
OR
According to your backend, the response is an object. Change this.repo.login return type to any.
I am developing an app in React Native and I want to implement logging in with Facebook.
I have an API in Node.js where I handle the logic for users to log in, etc.
I use passport.js to let users log in with either Facebook or traditional Email.
I am opening an URL in my API with SafariView which is just a regular "WebView" directly in my app.
I have tried using the following code:
class FacebookButton extends Component {
componentDidMount() {
// Add event listener to handle OAuthLogin:// URLs
Linking.addEventListener('url', this.handleOpenURL);
// Launched from an external URL
Linking.getInitialURL().then((url) => {
if (url) {
this.handleOpenURL({ url });
}
});
}
componentWillUnmount() {
Linking.removeEventListener('url', this.handleOpenURL);
}
handleOpenURL({ url }) {
// Extract stringified user string out of the URL
const [, user_string] = url.match(/user=([^#]+)/);
this.setState({
// Decode the user string and parse it into JSON
user: JSON.parse(decodeURI(user_string))
});
if (Platform.OS === 'ios') {
SafariView.dismiss();
}
}
openURL(url) {
if (Platform.OS === 'ios') {
SafariView.show({
url: url,
fromBottom: true,
});
} else {
Linking.openURL(url);
}
}
render() {
return (
<Button
onPress={() => this.openURL('https://mywebsite.com/api/auth/facebook')}
title='Continue with Facebook'
...
so I guess I will have to do the authentication on URL https://mywebsite.com/api/auth/facebook and then send the user to an url that looks something like OAuthLogin://..., but I am not entirely sure how to use it.
Can anyone help me move in the right direction?
import { LoginManager, AccessToken } from 'react-native-fbsdk'; // add this file using npm i react-native-fbsdk
Create function
const onFacebookButtonPress = async () => {
// Attempt login with permissions
const result = await LoginManager.logInWithPermissions(['public_profile', 'email']);
if (result.isCancelled) {
throw 'User cancelled the login process';
}
// Once signed in, get the users AccesToken
const userInfo = await AccessToken.getCurrentAccessToken();
if (!userInfo) {
throw 'Something went wrong obtaining access token';
}
console.log('user info login', userInfo)
// Create a Firebase credential with the AccessToken
const facebookCredential = auth.FacebookAuthProvider.credential(userInfo.accessToken);
setGoogleToken(userInfo.accessToken)
// Sign-in the user with the credential
return auth().signInWithCredential(facebookCredential)
.then(() => {
//Once the user creation has happened successfully, we can add the currentUser into firestore
//with the appropriate details.
console.log('current User ####', auth().currentUser);
var name = auth().currentUser.displayName
var mSplit = name.split(' ');
console.log("mSplit ",mSplit);
let mUserDataFacebook = {
user_registration_email: auth().currentUser.email,
user_registration_first_name: mSplit[0],
user_registration_last_name: mSplit[1],
registration_type: 'facebook',
user_registration_role: "Transporter",
token: userInfo.accessToken,
user_image : auth().currentUser.photoURL,
};
console.log('mUserDataFacebook',mUserDataFacebook)
LoginWithGoogleFacebook(mUserDataFacebook) /// Call here your API
firestore().collection('users').doc(auth().currentUser.uid) //// here you can add facebook login details to your firebase authentication.
.set({
fname: mSplit[0],
lname: mSplit[1],
email: auth().currentUser.email,
createdAt: firestore.Timestamp.fromDate(new Date()),
userImg: auth().currentUser.photoURL,
})
//ensure we catch any errors at this stage to advise us if something does go wrong
.catch(error => {
console.log('Something went wrong with added user to firestore: ', error);
})
})
}
Call this function on button press onFacebookButtonPress()
For android need to setup and add facebook id in
android/app/src/main/res/values/strings.xml file
add these two lines.
YOUR_FACEBOOK_ID
fbYOUR_FACEBOOK_ID //Don't remove fb in this string value
/////////////add this code in AndroidMainfest.xml file
//////////This code add in MainApplication.java file
import com.facebook.FacebookSdk;
import com.facebook.appevents.AppEventsLogger;
/////////add code build.gradle file
implementation 'com.facebook.android:facebook-android-sdk:[5,6)'
So I am working on an angular2 application and am trying to generate a JWT after logging in so that a user's profile information can be obtained. I can successfully login and that's when I generate the token. After logging in I route the user to the profile page and that's where I call my api to get the user information. All of this only works after I login and refresh to page.
this.auth_service
.Login(this.email, this.password)
.subscribe(
data => {
this.global_events.change_nav_bar.emit(true)
console.log('logged in successfully: ' + data)
this.router.navigate(['/profile'])
})
// auth_service above calls this method
Login(email, password): Observable<boolean>
{
return this.http
.post('/api/login', JSON.stringify({email: email, password: password}), this.Get_Headers('no_auth'))
.map(Handle_Response)
function Handle_Response(response: Response)
{
let token = response.json() && response.json().token
if(token)
{
this.token = token
localStorage.setItem('current_user', JSON.stringify({ email: email, token: token }))
return true
}
else
return false
}
}
// Then in my profile component I do this. I have experimented with different timeout times.
ngOnInit(): void
{
this.global_events.change_nav_bar.emit(true)
setTimeout(() => this.Get_User_Data(), 10000)
}
I solved this (not really solved but found another solution) by just pulling the token directly from localStorage instead of setting in the authenticationService