I would like to call an API using Postman, but unfortunately I can't because we have implemented a confirm dialog that blocks the api.
I have our credentials for username and password. But I would like just to ask if it's possible to automate or programmatically fill the username and password and auto-submit using Javscript or ReactJS?
axios.get('https://test.com/sample-response')
.then(function (response) {
// handle success
console.log(response);
});
Using axios interceptors to add the basic auth header to every request. For example:
const username = 'dd';
const password = '##';
const token = Buffer.from(`${username}:${password}`, 'utf8').toString('base64');
axios.interceptors.request.use(config => {
config.headers['Authorization'] = `Basic ${token}`;
return config;
});
axios.get('https://example.com')
.then(response => {
// handle success
})
.catch(error => {
// handle error
});
I hope this helps you with your query. 😊
Related
Here is my router
router.post("/login", async (req, res) =>
{
try
{
const user = await User.findByCredentials(req.body.email, req.body.password)
// console.log(user)
const token = await user.generateAuthToken()
// console.log(token)
res.redirect("/takvim")
}
catch(e)
{
res.status(400).redirect("/")
}
})
Here is my user model that I use in the function above
UserSchema.methods.generateAuthToken = async function ()
{
const user = this
const token = jwt.sign({_id: user._id.toString()}, "secret")
user.tokens = user.tokens.concat({token})
await user.save()
return token
}
UserSchema.statics.findByCredentials = async function (emails, passwords)
{
const user = await User.findOne({email: emails})
console.log(user)
const isMatch = await bcrypt.compare(passwords, user.password)
if(!isMatch)
{
throw new Error("unable to login")
}
return user
}
I am making the request from frontend using a button
$uyeolForm.addEventListener("submit", () =>
{
if(!$uyeolFormEmail.value.includes(".com"))
{
return $uyeolFormHata.innerHTML = "email geçersiz"
}
const xhr = new XMLHttpRequest();
let form = JSON.stringify({
email: $uyeolFormEmail.value,
password: $uyeolFormPassword.value
});
xhr.open("POST", "/login")
xhr.setRequestHeader('Content-type', 'application/json')
xhr.send(form);
})
Problem is when I am using the postman, application redirects me to the page i want and doesn't give an error.
When I send the request with button it still finds user but it doesn't redirect me to the page I expect and in the console i see the user(expected) and null which is not expected.
Thanks to everyone.
You are making an HTTP request with XMLHttpRequest when a submit event is triggered but you aren't preventing the default behaviour of a form submission.
So the XMLHttpRequest object is created and makes a request and then immediately after (and possibly cancelling the request depending on how quickly things go) the <form> is submitted to the URL specified in the action.
You said the endpoint was being hit twice, once where you get the user you expect and ones where you don't.
When you get the user you expect it is from the XHR submission.
When you don't, that is from the regular form submission (which won't be JSON encoded as HTML forms don't support JSON encoding so it doesn't find the user because it doesn't decode the data in the form correctly).
Since you said you wanted to redirect, don't use Ajax. Ajax is a method for making an HTTP request without leaving the current page.
Change the server-side code to accept the data in the format the <form> is encoding it (probably application/x-www-form-urlencoded unless you changed it with the enctype attribute).
You want to know what's the error message, always. Add a console.error(JSON.stringify(e))
before the response, and tell us what does it say.
catch(e)
{
console.error(JSON.stringify(e));
res.status(400).redirect("/");
}
If You're going to use application/json and application/x-www-form-urlencoded to support both ajax and usual form submission way - You've to redirect it on frontend level by reading Location header:
$uyeolForm.addEventListener("submit", (event) => {
event.preventDefault();
if(!$uyeolFormEmail.value.includes(".com")) {
return $uyeolFormHata.innerHTML = "email geçersiz"
}
fetch('/login', {
method: "POST",
credentials: "include",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
email: $uyeolFormEmail.value,
password: $uyeolFormPassword.value
})
})
.then(function(response) {
if (response.redirected) {
const redirectTo = response.headers.get('Location');
if (redirectTo) {
window.location.href = redirectTo;
return;
}
}
})
.catch(function(error) {
alert(error.message);
});
})
keep in mind that to support both application/json and application/x-www-form-urlencoded You've to attach 2 body parsers as middleware:
const bodyParser = require('body-parser');
router.use(bodyParser.urlencoded(true));
router.use(bodyParser.json());
I am using the ConnectyCube React Native SDK and have obtained an app auth token using their API. This token is required when making further requests - for example when logging in as a user. Their documentation says:
Upgrade session token (user login)
If you have an application session token, you can upgrade it to a user session by calling login method:
var userCredentials = {login: 'cubeuser', password: 'awesomepwd'};
ConnectyCube.login(userCredentials, function(error, user) {
});
The problem is it that when I use this method, I get an error in response saying 'Token is required'.
If I were interfacing with a REST API, I would put the token in the header of the request, but obviously in this instance I can't. So the question is, where do I put the token? I have it, the documentation just doesn't tell you how to use it! Any help appreciated.
Ok I came up with a fix. First of all I just tried passing the auth token in to the userCredntials object in the same way as in the documentation for social auth, that is absent from the description in my above code snippet taken from their docs.
Then I Promisified the API calls from within useEffect inside an async function to make sure everything was happening in the right order, and it works:
export default function App() {
const createAppSession = () => {
return new Promise((resolve, reject) => {
ConnectyCube.createSession((error, session) => {
!error
? resolve(session.token)
: reject(error, '=====1=====');
});
})
}
const loginUser = (credentials) => {
return new Promise((resolve, reject) => {
ConnectyCube.login(credentials, ((error, user) => {
!error
? resolve(user)
: reject(error, '=====2=====');
}));
})
}
useEffect(() => {
const ccFunc = async () => {
ConnectyCube.init(...config)
const appSessionToken = await createAppSession();
const userCredentials = { login: 'xxxxx', password: 'xxxxxxx', keys: { token: appSessionToken } };
const user = await loginUser(userCredentials);
console.log(user);
}
ccFunc()
}, []);
Hope it works....
please implement it by yourself...just take an understanding from code below.
code says: send the username and password to api...if all ok then authenticate else throw error ...if all ok..then store the returned token is asyncStorage...you can create the storage by any name you like...and use the token eveywhere in your app.
SignInUser = async () => {
this.setState({
username: this.state.username,
password:this.state.password,
})
if(this.state.username && this.state.password !== null){
try{
this.setState({
loading:true
})
const response = await fetch('YOUR API', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
username: this.state.username,
password: this.state.password
})
});
var promiseResponse = await response.json()
console.log(promiseResponse.token);
try {
await AsyncStorage.setItem('STORE_YOUR_LOGIN_TOKEN_HERE', JSON.stringify(promiseResponse.token));
console.log('Token Stored In Async Storage');
let tokenFromAsync = await AsyncStorage.getItem('STORE_YOUR_LOGIN_TOKEN_HERE');
console.log('Getting Token From Async...')
tokenFromAsync = JSON.parse(tokenFromAsync)
if(tokenFromAsync !== null){
console.log(tokenFromAsync);
this.setState({
loading:false
})
this.props.navigation.navigate('Tabnav');
}
} catch (error) {
// saving error
console.log(`ERROR OCCURED ${error}`)
}
//this.props.navigation.navigate('Tabnav')
} catch(error){
console.log(`COULDN'T SIGN IN ${error}`)
}
} else {
this.setState({
msg:'Invalid Credentials',
label:'red'
});
}
}
This is how i got the login to work in their sample react native app 1. i created a credentials object like this in my custom login function in src>components>AuthScreen>AuthForm.js
var credentials = {id:'',login: this.state.login,password: this.state.password}
2.I used their _signIn(credentials) function and set the 'id' attribute of my credentials object after their UserService.signin(credentials) resolved with a user object. (the resolved user object contained the logged-in user's id i.e user.id). Then it worked. This is how the code looked for the signin after the little tweak.
loginUser() { //my custom signin function
var credentials = {id:'',login: this.state.login,password: this.state.password} //my credentials object
this._signIn(credentials)
}
_signIn(userCredentials) { //their signin function
this.props.userIsLogging(true);
UserService.signin(userCredentials)
.then((user) => {
userCredentials.id = user.id //setting id of my credentials object after promise resolved
ChatService.connect(userCredentials) //using my credentials object with id value set
.then((contacts) => {
console.warn(contacts)
this.props.userLogin(user);
this.props.userIsLogging(false);
Actions.videochat(); //login worked
})
.catch(e => {
this.props.userIsLogging(false);
alert(`Error.\n\n${JSON.stringify(e)}`);
})
})
.catch(e => {
this.props.userIsLogging(false);
alert(`Error.\n\n${JSON.stringify(e)}`);
})
}
I'm trying to set up authentication using React and Laravel RESTFUL API. The issue is that I get info by clicking on the Login button. I want to complete the authentication by sending the data to the Laravel API and redirects to another page if it's verified and authenticated.
Thanks for helping me!
responseGoogle = (response) => {
console.log(response);
}
toggleLoggedIn = () =>
this.setState(state => {
return { isLoggedIn: !state.isLoggedIn };
});
onSuccess = googleUser => {
this.toggleLoggedIn();
let user = googleUser.getBasicProfile();
let id_token = googleUser.getAuthResponse().id_token;
console.log('google user obj', user);
console.log('google_id_token', id_token);
axios.post(`http://127.0.0.1:8000/api/api/google/callback`)
.then(res => {
console.log('Signed in as: ' + res.responseText);
});
}
<GoogleLogin
clientId="Client id"
buttonText="Login"
onSuccess={this.onSuccess}
onFailure={this.responseGoogle}
cookiePolicy={'single_host_origin'}
/>
I actually get Infos "in console" when clicking on the button. But I want to send them to the server and complete the authentication. Then redirect to another page.
Ok, so I have a Login.js which has the onSubmit function which redirects the page to UploadScreen.js:
Login.js:
onSubmit = (e) => {
const errors = this.validate(this.state);
this.setState({ errors });
e.preventDefault();
var apiBaseUrl = "http://127.0.0.1:8000/api/auth/login";
var self = this;
var payload={
"email":this.state.email,
"password":this.state.password
}
var config = {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
withCredentials: false
}
axios.post(apiBaseUrl, payload, config)
.then(function (response) {
console.log(response);
if(response.status == 200){
browserHistory.push('/upload');
self.setState({
redirect_to_upload : true
})
}
else if(response.status == 204){
console.log("Username password do not match");
alert("username password do not match")
}
else{
console.log("Username does not exists");
alert("Username does not exist");
}
})
.catch(function (error) {
console.log(error);
});
}
this is the response I get
so now, in the UploadScreen.js there is another endpoint I am calling, the endpoint http://127.0.0.1:8000/api/materials (GET) but I cannot access it because I need a token, and that token is provided with the response I got from earlier as highlighted.
In postman, it's like this
I won't be able to get anything if I don't provide the token
so my 1st question is:
How can I add the token I got from the onSubmit function earlier that is located in Login.js to this GET request I want to send now? (I am in UploadScreen.js)
and my second question is:
what if I want to get the uuid on that response (as highlighted) and make it the value of a Form.Input for example, and that form input is located on a different js file?
class UploadScreen extends Component {
constructor(){
super();
this.state={
profile_id: '',
errors: {}
}
}
<Form.Input
type='text'
name='profile_id'
value={} <<< what should I do, to be able to make the value to the uuid(in response, and make it appear as the placeholder of the input
I apologize for my english and I hope someone can help me with a specific answer because I am new to React Programming. Thanks
You can save it in localStorage and then set it as default headers so later you can use it on server to verify if the user is authenticated or not for that particular request.
axios.post(apiBaseUrl, payload, config)
.then(function (response) {
console.log(response);
if(response.status == 200){
localStorage.setItem('jwt',res.data.token);//add this
setHeader(res.data.token);// add this
browserHistory.push('/upload');
self.setState({
redirect_to_upload : true
})
}
you setHeader.js
import axios from 'axios'
import jwt from 'jsonwebtoken'
export default function setAuthToken(token){
if(token){
localStorage.setItem('jwt',token)
axios.defaults.headers.common['Authorization'] = `Bearer ${token}`
}
else{
delete axios.defaults.headers.common['Authorization']
}
}
Now on server like express.js you can
app.post('baseUrl',function(req,res){
var header = req.headers['authorization']
if(header){
var token = header.split(' ')[1]
//verify your jwt here
if(userIsAllowed){
//process
res.send('hello')
}else{
res.status(404).send()
}
}
})
Now only problem left is when user refresh the page then headers will be reset to handle that you can (in you index.js where all routes are imported and rendered (render<Router>....</Router>,document.getElementById('root'))
....
if(localStorage.getItem('jwt')){
setToken('token',localStorage.getItem('jwt'))
}
....
Judging by the amount of information you provided, here is what I understood.
You call an api and navigate to upload screen, but you need some data from the api which should already be present on the upload screen so that you can perform further action.
So, you'll be required to pass extra parameters to the screen you are navigating to. Assuming you are using react-router ( and if you aren't, I'll recommend it, it makes routing life easy)
Now, assuming you have the history object already in scope, you can do -
this.props.history.push({pathname:'/upload', token: response.data.current_user.uuid})
And now when you console.log(this.props.location.token) you can find the value which you can use
Hope this helps.
You can always setState your token (first you should create an empty state for token) and then pass it down as a props to another component.
And you can access your token via
console.log(response.data.current_user.token)
I'm building the frontend for a basic CRUD app that will interact with an external API.
I'm attempting to build a simple login form that works by
sending a POST request (username and password) to an external API for validation, getting a response and storing the user information in a session.
We have a list of users already in our API. Using a tool like Postman, I would confirm the user exists when we POST the correct credentials and get a response:
POST /api/v1/login
{
"email": "email#gmail.com",
"password": "password123"
}
Response:
{
"data": {
"team_id": "0987654321",
"name": "John",
"email": "email#gmail.com",
"access_token": "1234567890qwerty"
}
}
I'm new to react, and it's been a while since I've used Javascript, and I don't quite understand how this works. Any help would be appreciated.
Apologies if this info is a little vague.
Once you get the response from your API you should then store any non sensitive information that you may need in your front-end. If you are using something like JWT you can store the token in the localstorage and use jwt-decode library for reading it.
fetch(this.email.value, this.password.value)
.then(res => {
localStorage.setItem('id_token', res.token) // Store token
})
.catch(err => {
console.log(err);
});
It also pretty common in react to have utility or helper file that handles your authorization
/utils/AuthUtility
class AuthService{
login(email, password) {
return this.fetch('/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
email,
password
})
})
.then(res => {
if(res.type == 'success'){
this.setToken(res.token) // Setting the token in localStorage
return Promise.resolve(res);
} else {
return Promise.reject(res)
}
})
}
// Other available methods
setToken(idToken) {
// Saves user token to localStorage
localStorage.setItem('id_token', idToken)
}
getProfile() {
// Using jwt-decode npm package to decode the token
return decode(localStorage.getItem('id_token'); // assuming you have jwt token then use jwt-decode library
}
}
then in your login component
//components/login.js
import AuthUtility from './utils/AuthUtility';
login = (e) => {
this.Auth.login(this.email.value, this.password.value)
.then(res => {
this.props.history.push('/protectedRoute');
})
.catch(err => {
console.log(error);
});
}
I'd use the very popular http client 'axios'
Install axios in your react app
npm install axios --save
Add this code to the click\submit handler function of your login form:
axios.post('http://[PATH_HERE]/api/v1/login', {
"email": "email#gmail.com",
"password": "password123"
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
Creating login component on react using ant design is simple please follow below steps
To install ant design in react
npm install antd
and then install ant icons
npm install --save #ant-design/icons for more info
For more info please click here