this.http.post doesn't not send params in angular 4 - php

I need to create a login system, I try to send the params to the PHP server.
Angular app
return this.http.post<any>('/s/login/index.php', {
username: username,
password: password
}).map(user => {
console.log(username);
// login successful if there's a jwt token in the response
if (user) {
// store user details and jwt token in local storage to keep user logged in between page refreshes
}
return user;
});
}
PHP server
if($_SERVER["REQUEST_METHOD"] == "POST"){
// Check if username is empty
if(empty(trim($_POST["username"]))){
$username_err = 'Please enter username.';
$resp->body->message=$username_err;
$resp=json_encode($resp);
echo $resp;
}
But the server always returns
{status: "400", body: {message: "Please enter username."}}

It is because you are not setting headers.
first import necessary modules
import {HttpClient,HttpHeaders} from '#angular/common/http';
import {URLSearchParams} from '#angular/http';
try it this way.
let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
let options = {
headers: headers
};
let body = new URLSearchParams();
body.set('username', username);
body.set('password', password);
return this.http.post<any>('/s/login/index.php', body, options).map(user => {
console.log(username);
// login successful if there's a jwt token in the response
if (user) {
// store user details and jwt token in local storage to keep user logged in between page refreshes
}
return user;
});
}
Tell me if it does not work. I am here !

Related

how to use php sessions and svelte together

I'm using php for my application backend. I created a authentication system with two loginUser.php and loginCheck.php
In loginUser.php when username and password is correct:
session_start();
session_regenerate_id();
$_SESSION['bookstore_username'] = $_POST['username'];
session_write_close();
$response = array('status' => true, 'message' => 'user successfully authorized.', 'data' => $row);
echo json_encode($response);
Then in loginCheck.php
session_start();
if (isset($_SESSION["bookstore_username"]) && $_SESSION["bookstore_username"] == $_POST['username']) {
$response = array('status' => true, 'message' => "user is logged in.");
echo json_encode($response);
} else {
$response = array('status' => false, 'message' => "user is not logged in.");
echo json_encode($response);
}
When i testing it in Postman Application everything is fine and response showed me user logged in but in svelte app after doing a user login when i check login stat response is always false and session is null.
const checkUserIsLoggedIn = async (): Promise<void> => {
const url = ORIGIN + "Backend/api/user/loginCheck.php";
let data = new FormData();
data.append("username", userInformationStore?.get().username);
const res = await fetch(url, {
method: "POST",
body: data,
});
let response = await res.json();
console.log(response);
};
Assuming the session relies on a cookie, the only explanation I see for the Session being null is that the session cookie is not being passed back to your back-end. By default, fetch only allows same-origin cookies. Try adding the following option to your fetch operation to allow cookies to be passed in cross-origin requests:
const res = await fetch(url, {
method: "POST",
body: data,
credentials: "include",
});
See this paragraph in the Fetch API documentation for details.

how to manage the successfully response from a post method in angular 5

Okay, I'm stuck with a login. It suppose to send this data with a post method:
POST URL:
/user/login?_format=json
Header:
Content-Type: application/json
POST data:
{
"name": "username",
"pass": "password"
}
I do all that with the login() function:
login (user: User): Observable<User> {
// let's make the url
const url = `${this.mainUrl}/user/login?_format=json`;
// the data comes in the 'user' array
// the header is define above "Content-Type": "application/json"
const loginReturn = this.http.post(url, user, header);
return loginReturn
.pipe(
tap((user: User) => this.log(`Looged user id=${user.id}`)),
catchError(this.handleError<User>('login'))
);
}
And it works, but i dont know how to manage this Successful response:
{
"current_user":{
"uid": "1",
"roles":[
"authenticated",
"administrator"
],
"name": "username"
},
"csrf_token": "asda09820380_2238019280dk09n908asjdlkajdaoa",
"logout_token": "asdasd09a8sdaslkdasl-asdasdklsajdlkasdjlksj"
}
I need to use the csrf_token and the logout_token for future get methods.
For log out, use the logout token in a GET request. The ends the user's session.
/user/logout?_format=json&token=asdasd09a8sdaslkdasl-asdasdklsajdlkasdjlksj
GET login status:
/user/login_status?_format=json
GET token:
/rest/session/token
I want to know how to use the tokens coming from the post method...
thanks you, and sorry for the silly question.
Here is a basic example
Subscribe to your login method to log the user in from your authentication service
//authenticationService.ts
doLogin()
{
yourService.login().subscribe(user=>
{
//set your own flags to log the user in here and store relevant info
localStorage.setItem('currentUser', JSON.stringify(user));
localStorage.setItem('currentCSRFToken', user.csrf_token);
})
}
doLogout()
{
let logoutToken = JSON.parse(localStorage.getItem('currentUser')).logout_token;
yourService.logout(logoutToken).subscribe(resp=>
{
//set your own flags to log the user out here and reset session data
localStorage.setItem('currentUser', null);
localStorage.setItem('currentCSRFToken', null);
})
}
And add this logout method to the service where you declared the loginmethod
//yourService.ts
logout (logoutToken: string): Observable<any> { //don't know what your logout method returns
const url = `${this.mainUrl}/user/logout?_format=json&token=${logoutToken}`;
return this.http.get(url, user);
}

How to set up Google+ Sign-In for server-side apps for a website?

I am trying to add a sign in with google+ button on my website just to retrieve basic information.
but the documentation doesnt seem to make any sense to me.
(https://developers.google.com/+/web/signin/server-side-flow)
it appears out of date and not complete and there seems to be various api library's that can be used.
Can anyone explain all this more clearly or tell me how i should go about making this work and which api library to use etc?
a full sample with code would be very helpful.
thanx
Ok so i will add more detail. google development page gives this as an example for a login button :
<html>
<head>
<!-- BEGIN Pre-requisites -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js">
</script>
<script src="https://apis.google.com/js/client:platform.js?onload=start" async defer>
</script>
<!-- END Pre-requisites -->
</head>
<body>
<div id="signinButton">
<span class="g-signin"
data-scope="https://www.googleapis.com/auth/plus.login"
data-clientid="your-client-id"
data-redirecturi="postmessage"
data-accesstype="offline"
data-cookiepolicy="single_host_origin"
data-callback="signInCallback">
</span>
</div>
<div id="result"></div>
<script>
function signInCallback(authResult) {
if (authResult['code']) {
// Hide the sign-in button now that the user is authorized, for example:
$('#signinButton').attr('style', 'display: none');
// Send the code to the server
$.ajax({
type: 'POST',
url: 'plus.php?storeToken',
contentType: 'application/octet-stream; charset=utf-8',
success: function(result) {
// Handle or verify the server response if necessary.
// Prints the list of people that the user has allowed the app to know
// to the console.
console.log(result);
if (result['profile'] && result['people']){
$('#results').html('Hello ' + result['profile']['displayName'] + '. You successfully made a server side call to people.get and people.list');
} else {
$('#results').html('Failed to make a server-side call. Check your configuration and console.');
}
},
processData: false,
data: authResult['code']
});
} else if (authResult['error']) {
// There was an error.
// Possible error codes:
// "access_denied" - User denied access to your app
// "immediate_failed" - Could not automatially log in the user
// console.log('There was an error: ' + authResult['error']);
}
}
</script>
</body>
</html>
but it also provides:
<?php
// Create a state token to prevent request forgery.
// Store it in the session for later validation.
$state = md5(rand());
$app['session']->set('state', $state);
// Set the client ID, token state, and application name in the HTML while
// serving it.
return $app['twig']->render('index.html', array(
'CLIENT_ID' => CLIENT_ID,
'STATE' => $state,
'APPLICATION_NAME' => APPLICATION_NAME
));
// Ensure that this is no request forgery going on, and that the user
// sending us this connect request is the user that was supposed to.
if ($request->get('state') != ($app['session']->get('state'))) {
return new Response('Invalid state parameter', 401);
}
$code = $request->getContent();
$gPlusId = $request->get['gplus_id'];
// Exchange the OAuth 2.0 authorization code for user credentials.
$client->authenticate($code);
$token = json_decode($client->getAccessToken());
// Verify the token
$reqUrl = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=' .
$token->access_token;
$req = new Google_HttpRequest($reqUrl);
$tokenInfo = json_decode(
$client::getIo()->authenticatedRequest($req)->getResponseBody());
// If there was an error in the token info, abort.
if ($tokenInfo->error) {
return new Response($tokenInfo->error, 500);
}
// Make sure the token we got is for the intended user.
if ($tokenInfo->userid != $gPlusId) {
return new Response(
"Token's user ID doesn't match given user ID", 401);
}
// Make sure the token we got is for our app.
if ($tokenInfo->audience != CLIENT_ID) {
return new Response(
"Token's client ID does not match app's.", 401);
}
// Store the token in the session for later use.
$app['session']->set('token', json_encode($token));
$response = 'Succesfully connected with token: ' . print_r($token, true);
?>
But it doesnt say where to put that last bit of code or how to refer to an api library or where to put the secret or anything. so i could do with some pointing in the righ direction please?
ok so if anyone else is having trouble.
i followed the tutorial on this link
I downloaded the api library from there, changed the configs file and used the example that is provided and it worked fine.
to make it work on a localhost you have to set your Authorized JavaScript origins to a localhost:# for example http://localhost:12345
then to make your browser accept the folder or the signin page in command prompt type in
cd c:/the/path/of/the/downloaded/api/example
then type in:
php -S localhost:12345
hope that helps anyone

How to solve the error: MethodNotAllowedHttpException

I am using Symfony to connect with Google Plus. Here is my code about connecting google after login and get access token:
$app->match('/connect', function (Request $request) use ($app, $client) {
$token = $app['session']->get('token');
if (empty($token)) {
// Ensure that this is no request forgery going on, and that the user
// sending us this connect request is the user that was supposed to.
if ($request->get('state') != ($app['session']->get('state'))) {
return new Response('Invalid state parameter', 401);
}
// Normally the state would be a one-time use token, however in our
// simple case, we want a user to be able to connect and disconnect
// without reloading the page. Thus, for demonstration, we don't
// implement this best practice.
//$app['session']->set('state', '');
$code = $request->getContent();
// Exchange the OAuth 2.0 authorization code for user credentials.
$gPlusId = $request->get['gplus_id'];
$client->authenticate($code);
$token = json_decode($client->getAccessToken());
// Verify the token
$reqUrl = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=' .
$token->access_token;
$req = new Google_HttpRequest($reqUrl);
$tokenInfo = json_decode(
$client::getIo()->authenticatedRequest($req)->getResponseBody());
// If there was an error in the token info, abort.
if ($tokenInfo->error) {
return new Response($tokenInfo->error, 500);
}
// Make sure the token we got is for the intended user.
if ($tokenInfo->userid != $gPlusId) {
return new Response(
"Token's user ID doesn't match given user ID", 401);
}
// Make sure the token we got is for our app.
if ($tokenInfo->audience != CLIENT_ID) {
return new Response(
"Token's client ID does not match app's.", 401);
}
//$_SESSION['token']=$token;
// You can read the Google user ID in the ID token.
// "sub" represents the ID token subscriber which in our case
// is the user ID. This sample does not use the user ID.
$attributes = $client->verifyIdToken($token->id_token, CLIENT_ID)
->getAttributes();
$gplus_id = $attributes["payload"]["sub"];
// Store the token in the session for later use.
$app['session']->set('token', json_encode($token));
$response = 'Successfully connected with token: ' . print_r($token, true);
}
return new Response($response, 200);
})->method('POST');
In the html file I use ajax to call the previous PHP code:
connectServer: function() {
$.ajax({
type: 'POST',
url: window.location.href + '/connect?state={{ STATE }}',
cache:false,
contentType: 'application/octet-stream; charset=utf-8',
success: function(result) {
console.log(result);
// helper.people();
},
error:function(e){
console.log(e);
},
processData: false,
data: this.authResult.code
});
But I always get an error: MethodNotAllowedHttpException: No route found for "GET /connect": Method Not Allowed (Allow: POST).
How can I solve the error?
It's looks like this one: No route found for "GET /user/register": Method Not Allowed (Allow: POST)
You have to define requirements _method for you route, like:
routeName:
pattern: /yourPattern
defaults: { _controller: AcmeBundle:Sth:action }
requirements:
_method: POST|GET

Facebook Graph API, how to get users email?

I'm using the Graph API, but I can't figure out how to get a logged-in users email address.
The intro to Graph states "The Graph API can provide access to all of the basic account registration data you would typically request in a sign-up form for your site, including name, email address, profile picture, and birthday"
All well and good, but how do I access that info?
This is what I have so far:
$json = $facebook->api('/me');
$first = $json['first_name']; // gets first name
$last = $json['last_name'];
The only way to get the users e-mail address is to request extended permissions on the email field. The user must allow you to see this and you cannot get the e-mail addresses of the user's friends.
http://developers.facebook.com/docs/authentication/permissions
You can do this if you are using Facebook connect by passing scope=email in the get string of your call to the Auth Dialog.
I'd recommend using an SDK instead of file_get_contents as it makes it far easier to perform the Oauth authentication.
// Facebook SDK v5 for PHP
// https://developers.facebook.com/docs/php/gettingstarted/5.0.0
$fb = new Facebook\Facebook([
'app_id' => '{app-id}',
'app_secret' => '{app-secret}',
'default_graph_version' => 'v2.4',
]);
$fb->setDefaultAccessToken($_SESSION['facebook_access_token']);
$response = $fb->get('/me?locale=en_US&fields=name,email');
$userNode = $response->getGraphUser();
var_dump(
$userNode->getField('email'), $userNode['email']
);
Open base_facebook.php
Add Access_token at function getLoginUrl()
array_merge(array(
'access_token' => $this->getAccessToken(),
'client_id' => $this->getAppId(),
'redirect_uri' => $currentUrl, // possibly overwritten
'state' => $this->state),
$params);
and Use scope for Email Permission
if ($user) {
echo $logoutUrl = $facebook->getLogoutUrl();
} else {
echo $loginUrl = $facebook->getLoginUrl(array('scope' => 'email,read_stream'));
}
Just add these code block on status return, and start passing a query string object {}. For JavaScript devs
After initializing your sdk.
step 1: // get login status
$(document).ready(function($) {
FB.getLoginStatus(function(response) {
statusChangeCallback(response);
console.log(response);
});
});
This will check on document load and get your login status check if users has been logged in.
Then the function checkLoginState is called, and response is pass to statusChangeCallback
function checkLoginState() {
FB.getLoginStatus(function(response) {
statusChangeCallback(response);
});
}
Step 2: Let you get the response data from the status
function statusChangeCallback(response) {
// body...
if(response.status === 'connected'){
// setElements(true);
let userId = response.authResponse.userID;
// console.log(userId);
console.log('login');
getUserInfo(userId);
}else{
// setElements(false);
console.log('not logged in !');
}
}
This also has the userid which is being set to variable, then a getUserInfo func is called to fetch user information using the Graph-api.
function getUserInfo(userId) {
// body...
FB.api(
'/'+userId+'/?fields=id,name,email',
'GET',
{},
function(response) {
// Insert your code here
// console.log(response);
let email = response.email;
loginViaEmail(email);
}
);
}
After passing the userid as an argument, the function then fetch all information relating to that userid. Note: in my case i was looking for the email, as to allowed me run a function that can logged user via email only.
// login via email
function loginViaEmail(email) {
// body...
let token = '{{ csrf_token() }}';
let data = {
_token:token,
email:email
}
$.ajax({
url: '/login/via/email',
type: 'POST',
dataType: 'json',
data: data,
success: function(data){
console.log(data);
if(data.status == 'success'){
window.location.href = '/dashboard';
}
if(data.status == 'info'){
window.location.href = '/create-account';
}
},
error: function(data){
console.log('Error logging in via email !');
// alert('Fail to send login request !');
}
});
}
To get the user email, you have to log in the user with his Facebook account using the email permission. Use for that the Facebook PHP SDK (see on github) as following.
First check if the user is already logged in :
require "facebook.php";
$facebook = new Facebook(array(
'appId' => YOUR_APP_ID,
'secret' => YOUR_APP_SECRET,
));
$user = $facebook->getUser();
if ($user) {
try {
$user_profile = $facebook->api('/me');
} catch (FacebookApiException $e) {
$user = null;
}
}
If he his not, you can display the login link asking for the email permission :
if (!$user) {
$args = array('scope' => 'email');
echo 'Login with Facebook';
} else {
echo 'Logout';
}
When he is logged in the email can be found in the $user_profile array.
Hope that helps !
Assuming you've requested email permissions when the user logged in from your app and you have a valid token,
With the fetch api you can just
const token = "some_valid_token";
const response = await fetch(
`https://graph.facebook.com/me?fields=email&access_token=${token}`
);
const result = await response.json();
result will be:
{
"id": "some_id",
"email": "name#example.org"
}
id will be returned anyway.
You can add to the fields query param more stuff, but you need permissions for them if they are not on the public profile (name is public).
?fields=name,email,user_birthday&token=
https://developers.facebook.com/docs/facebook-login/permissions
You can retrieve the email address from the logged in user's profile. Here is the code snippet
<?php
$facebook = new Facebook(array(
'appId' => $initMe["appId"],
'secret' => $initMe["appSecret"],
));
$facebook->setAccessToken($initMe["accessToken"]);
$user = $facebook->getUser();
if ($user) {
$user_profile = $facebook->api('/me');
print_r($user_profile["email"]);
}
?>
First, activate your application at the Facebook Developer center. Applications in development mode are not allowed to retrieve the e-mail field.
If the user is not logged in, you need to login and specify that your application/site will need the e-mail field.
FB.login(
function(response) {
console.log('Welcome!');
},
{scope: 'email'}
);
Then, after the login, or if the user is already logged, retrieve the e-mail using the Facebook API, specifying the field email:
FB.api('/me', {fields: 'name,email'}, (response) => {
console.log(response.name + ', ' + response.email);
console.log('full response: ', response);
});
https://graph.facebook.com/me
will give you info about the currently logged-in user, but you'll need to supply an oauth token. See:
http://developers.facebook.com/docs/reference/api/user
The email in the profile can be obtained using extended permission but I Guess it's not possible to get the email used to login fb. In my app i wanted to display mulitple fb accounts of a user in a list, i wanted to show the login emails of fb accounts as a unique identifier of the respective accounts but i couldn't get it off from fb, all i got was the primary email in the user profile but in my case my login email and my primary email are different.
Make sure your Facebook application is published. In order to receive data for email, public_profile and user_friends your app must be made available to public.
You can disable it later for development purposes and still get email field.
The following tools can be useful during development:
Access Token Debugger: Paste in an access token for details
https://developers.facebook.com/tools/debug/accesstoken/
Graph API Explorer: Test requests to the graph api after pasting in your access token
https://developers.facebook.com/tools/explorer
Make sure to fully specify the version number of the API as something like "v2.11" and not "2.11"
I'm not sure what it defaults to if this is incorrect, but I got some odd errors trying to just retrieve the email when I missed the v.
For me the problem with collecting user's email addres on PHP side (getGraphUser() method) was, that the default behavior of facebook-rendered button (on WEBSIDE side, created with xfbml=1) is to implicity calling FB.login() with the scope NOT including "email".
That means you MUST:
1) call
FB.login(....,{scope: email})
manifestly, creating your own button to start login process
OR
2) add scope="email" attribute to the xfbml button
<div class="fb-login-button" data-size="large" data-button-type="continue_with" data-
layout="rounded" data-auto-logout-link="false" data-use-continue-as="true" data-
width="1000px" scope="email"></div>
to be able to collect email address on PHP side.
Hope it helps.

Categories