REST User registration and Login through Api Key - codeigniter

I am not new to codeignitor , but still i didn't used they feature called 'API keys' authentication.
What i want to do ?
Register a user in my_users table and there is apikey as column that should store and generate unique api while user registration.
Login User , user give username , password and it get response as logged in if correct information is given , with it's respective apikey in my_users table.
After login i want to use apikey for all other user related calls like bookATask with header as X-API-KEY , which will allow me to control user session at client side and secure login and sign system.
Problem in Setup:
I am being asked each time i make a request to pass X-API-KEY which is wrong because , maybe there is call register_post in User controller which register users and Api key cannot be passed in headers unless it is generated in this method right?
I am just getting status:FALSE and error:Invalid Api key on each call i make.
What am i doing?
(Only changed code)
application/config/rest.php
defined('BASEPATH') OR exit('No direct script access allowed');
$config['force_https'] = FALSE;
$config['rest_default_format'] = 'json';
$config['rest_supported_formats'] = [
'json',
'array',
'csv',
'html',
'jsonp',
'php',
'serialized',
'xml',
];
$config['rest_status_field_name'] = 'status';
$config['rest_message_field_name'] = 'error';
$config['enable_emulate_request'] = TRUE;
$config['rest_realm'] = 'REST API';
$config['rest_auth'] = 'basic';
$config['auth_source'] = '';
$config['allow_auth_and_keys'] = TRUE;
$config['auth_library_class'] = '';
$config['auth_library_function'] = '';
$config['auth_override_class_method_http']['user']['register']['post'] = 'none';
$config['auth_override_class_method_http']['user']['login']['post'] = 'none';
$config['rest_valid_logins'] = ['user1' => '12345'];
$config['rest_ip_whitelist_enabled'] = FALSE;
$config['rest_ip_whitelist'] = '';
$config['rest_ip_blacklist_enabled'] = FALSE;
$config['rest_ip_blacklist'] = '';
$config['rest_database_group'] = 'default';
$config['rest_keys_table'] = 'my_users';
$config['rest_enable_keys'] = TRUE;
$config['rest_key_column'] = 'apikey';
$config['rest_limits_method'] = 'ROUTED_URL';
$config['rest_key_length'] = 40;
$config['rest_key_name'] = 'X-API-KEY';
$config['rest_enable_logging'] = TRUE;
$config['rest_logs_table'] = 'app_logs';
$config['rest_enable_access'] = FALSE;
$config['rest_access_table'] = 'access';
$config['rest_logs_json_params'] = FALSE;
$config['rest_enable_limits'] = TRUE;
$config['rest_limits_table'] = 'app_limits';
$config['rest_ignore_http_accept'] = FALSE;
$config['rest_ajax_only'] = FALSE;
$config['rest_language'] = 'english';
$config['check_cors'] = FALSE;
$config['allowed_cors_headers'] = [
'Origin',
'X-Requested-With',
'Content-Type',
'Accept',
'Access-Control-Request-Method'
];
$config['allowed_cors_methods'] = [
'GET',
'POST',
'OPTIONS',
'PUT',
'PATCH',
'DELETE'
];
$config['allow_any_cors_domain'] = FALSE;
$config['allowed_cors_origins'] = [];
application/config/autoload.php
$autoload['libraries'] = array('database');
controllers/api/Key.php
defined('BASEPATH') OR exit('No direct script access allowed');
require APPPATH . '/libraries/REST_Controller.php';
class Key extends REST_Controller {
protected $methods = [
'index_put' => ['level' => 10, 'limit' => 10],
'index_delete' => ['level' => 10],
'level_post' => ['level' => 10],
'regenerate_post' => ['level' => 10],
];
public function index_put()
{
$key = $this->_generate_key();
$level = $this->put('level') ? $this->put('level') : 1;
$ignore_limits = ctype_digit($this->put('ignore_limits')) ? (int) $this->put('ignore_limits') : 1;
if ($this->_insert_key($key, ['level' => $level, 'ignore_limits' => $ignore_limits]))
{
$this->response([
'status' => TRUE,
'key' => $key
], REST_Controller::HTTP_CREATED); // CREATED (201) being the HTTP response code
}
else
{
$this->response([
'status' => FALSE,
'message' => 'Could not save the key'
], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code
}
}
public function index_delete()
{
$key = $this->delete('key');
if (!$this->_key_exists($key))
{
$this->response([
'status' => FALSE,
'message' => 'Invalid API key'
], REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code
}
$this->_delete_key($key);
$this->response([
'status' => TRUE,
'message' => 'API key was deleted'
], REST_Controller::HTTP_NO_CONTENT); // NO_CONTENT (204) being the HTTP response code
}
public function level_post()
{
$key = $this->post('key');
$new_level = $this->post('level');
if (!$this->_key_exists($key))
{
$this->response([
'status' => FALSE,
'message' => 'Invalid API key'
], REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code
}
if ($this->_update_key($key, ['level' => $new_level]))
{
$this->response([
'status' => TRUE,
'message' => 'API key was updated'
], REST_Controller::HTTP_OK); // OK (200) being the HTTP response code
}
else
{
$this->response([
'status' => FALSE,
'message' => 'Could not update the key level'
], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code
}
}
public function suspend_post()
{
$key = $this->post('key');
if (!$this->_key_exists($key))
{
$this->response([
'status' => FALSE,
'message' => 'Invalid API key'
], REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code
}
if ($this->_update_key($key, ['level' => 0]))
{
$this->response([
'status' => TRUE,
'message' => 'Key was suspended'
], REST_Controller::HTTP_OK); // OK (200) being the HTTP response code
}
else
{
$this->response([
'status' => FALSE,
'message' => 'Could not suspend the user'
], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code
}
}
public function regenerate_post()
{
$old_key = $this->post('key');
$key_details = $this->_get_key($old_key);
if (!$key_details)
{
$this->response([
'status' => FALSE,
'message' => 'Invalid API key'
], REST_Controller::HTTP_BAD_REQUEST); // BAD_REQUEST (400) being the HTTP response code
}
$new_key = $this->_generate_key();
if ($this->_insert_key($new_key, ['level' => $key_details->level, 'ignore_limits' => $key_details->ignore_limits]))
{
$this->_update_key($old_key, ['level' => 0]);
$this->response([
'status' => TRUE,
'key' => $new_key
], REST_Controller::HTTP_CREATED); // CREATED (201) being the HTTP response code
}
else
{
$this->response([
'status' => FALSE,
'message' => 'Could not save the key'
], REST_Controller::HTTP_INTERNAL_SERVER_ERROR); // INTERNAL_SERVER_ERROR (500) being the HTTP response code
}
}
private function _generate_key()
{
do
{
$salt = base_convert(bin2hex($this->security->get_random_bytes(64)), 16, 36);
if ($salt === FALSE)
{
$salt = hash('sha256', time() . mt_rand());
}
$new_key = substr($salt, 0, config_item('rest_key_length'));
}
while ($this->_key_exists($new_key));
return $new_key;
}
private function _get_key($key)
{
return $this->db
->where(config_item('rest_key_column'), $key)
->get(config_item('rest_keys_table'))
->row();
}
private function _key_exists($key)
{
return $this->db
->where(config_item('rest_key_column'), $key)
->count_all_results(config_item('rest_keys_table')) > 0;
}
private function _insert_key($key, $data)
{
$data[config_item('rest_key_column')] = $key;
$data['date_created'] = function_exists('now') ? now() : time();
return $this->db
->set($data)
->insert(config_item('rest_keys_table'));
}
private function _update_key($key, $data)
{
return $this->db
->where(config_item('rest_key_column'), $key)
->update(config_item('rest_keys_table'), $data);
}
private function _delete_key($key)
{
return $this->db
->where(config_item('rest_key_column'), $key)
->delete(config_item('rest_keys_table'));
}
}
(Method used in controller to generate Api key)
private function _generate_key()
{
do
{
// Generate a random salt
$salt = base_convert(bin2hex($this->security->get_random_bytes(64)), 16, 36);
// If an error occurred, then fall back to the previous method
if ($salt === FALSE)
{
$salt = hash('sha256', time() . mt_rand());
}
$new_key = substr($salt, 0, config_item('rest_key_length'));
}
while ($this->_key_exists($new_key));
return $new_key;
}
private function _key_exists($key)
{
return $this->db
->where(config_item('rest_key_column'), $key)
->count_all_results(config_item('rest_keys_table')) > 0;
}
On Database i have two extra tables app_limits , app_logs , and apikey column with varchar(40) in my_users table that's all , can anyone help me solving my issue , what am i doing wrong ?

I have found the answer myself , i just modifying these variables helped me :
$config['auth_override_class_method_http']['user']['customer_register']['post'] = 'none';
$config['auth_override_class_method_http']['user']['customer_login']['post'] = 'none';
these are basically exception methods for Api key which can be register and login , thanks myself

Related

Payment failed but order is Placed in Laravel with Stripe

I have integrated stripe payment in flutter app but After payment got failed even then order placed in Laravel database so please check, what I have done wrong.
Please check at save method, May be I am wrong and can't validate purchase response.
payment controller
public function makePayment(Request $request)
{
try{
$data = $request->input('cartItems');
$cartItems = json_decode($data, true);
$orderData = $request->input('order');
$selectPaymentOption = json_decode($orderData, true);
$totalAmount = 0.0;
foreach ($cartItems as $cartItem){
$order = new Order();
$order->order_date = Carbon::now()->toDateString();
$order->product_id = $cartItem['productId'];
$order->payment_type = $selectPaymentOption['paymentType'];
$order->user_id = $request->input('userId');
$order->quantity = $cartItem['productQuantity'];
$order->amount = ($cartItem['productPrice'] - $cartItem['productDiscount']);
$totalAmount+= $order->amount * $order->quantity;
$order->save();
}
if($selectPaymentOption['paymentType'] == 'Card'){
\Stripe\Stripe::setApiKey('sk_test_hJUgYYzeXtitxxxx71lK8nE00MELJJS8c');
$token = \Stripe\Token::create([
'card' => [
'number' => $request->input('cardNumber'),
'exp_month' => $request->input('expiryMonth'),
'exp_year' => $request->input('expiryYear'),
'cvc' => $request->input('cvcNumber')
]
]);
$charge = \Stripe\Charge::create([
'amount' => $totalAmount * 100,
'currency' => 'inr',
'source' => $token,
'receipt_email' => $request->input('email'),
]);
}
return response(['result' => true]);
} catch (\Exception $exception){
return response(['result' => $exception]);
}
}
and my Flutter's Post request is here.
I want to POST _makePayment method after complete payment successful.
void _makePayment(BuildContext context, Payment payment) async {
PaymentService _paymentService = PaymentService();
var paymentData = await _paymentService.makePayment(payment);
var result = json.decode(paymentData.body);
print(paymentData);
CartService _cartService = CartService();
this.widget.cartItems!.forEach((cartItem) {
_cartService.makeTheCartEmpty();
});
if (result['result'] == true) {
_showPaymentSuccessMessage(context);
Timer(Duration(seconds: 4), () {
Navigator.pop(context);
Navigator.push(
context, MaterialPageRoute(builder: (context) => HomeScreen()));
});
}
}
Referring to my comment above, this is the rough solution I suggested in your controller you have to switch the logic
public function makePayment(Request $request)
{
try{
$data = $request->input('cartItems');
$cartItems = json_decode($data, true);
$orderData = $request->input('order');
$selectPaymentOption = json_decode($orderData, true);
##Change your frontend logic to pass total amount as variable
$totalAmount = $request->totalAmount;
if($selectPaymentOption['paymentType'] == 'Card'){
##Never have any sk or pk in your controller, switch this to config('common.sk_test')
\Stripe\Stripe::setApiKey(config('common.sk_test'));
$token = \Stripe\Token::create([
'card' => [
'number' => $request->input('cardNumber'),
'exp_month' => $request->input('expiryMonth'),
'exp_year' => $request->input('expiryYear'),
'cvc' => $request->input('cvcNumber')
]
]);
$charge = \Stripe\Charge::create([
'amount' => $totalAmount * 100,
'currency' => 'inr',
'source' => $token,
'receipt_email' => $request->input('email'),
]);
}
##After the stripe transaction is finished you can foreach your cart and do what you need to your database
foreach ($cartItems as $cartItem){
$order = new Order();
$order->order_date = Carbon::now()->toDateString();
$order->product_id = $cartItem['productId'];
$order->payment_type = $selectPaymentOption['paymentType'];
$order->user_id = $request->input('userId');
$order->quantity = $cartItem['productQuantity'];
$order->amount = ($cartItem['productPrice'] - $cartItem['productDiscount']);
$order->save();
}
return response(['result' => true]);
} catch (\Exception $exception){
return response(['result' => $exception]);
}
}
For the config('common.sk_test') part of my answer, in you config folder you can create a new file where you have you custom app variables, so create a file for instance common.php and 'sk_test' that takes its value from you .env file

Hybridauth - The authorization state [state=HA-SOME_STATE_DATA] of this page is either invalid or has already been consumed

I am using Hybridauth with Codeigniter to implement social login buttons in my app. I just require Google, Facebook & LinkedIn social login button. I have successfully implemented the Google sign & sign up method but the same code does not work for Facebook & LinkedIn, Here is the error I am getting always this exception,
ops, we ran into an issue! The authorization state
[state=HA-RBNC6FHJ54VZAM1KTD7EI3SPYG08U2OLWQ9X] of this page is either
invalid or has already been consumed.Unable to get your data!Try after
some time.
My config file for hybriduath.
<?php
$config['hybridauth'] = [
//Location where to redirect users once they authenticate with a provider
'callback' => 'http://localhost/insurance-experts/auth/social_auth',
//Providers specifics
'providers' => [
'Google' => [
'enabled' => true,
'keys' => [
'id' => '...',
'secret' => '...',
],
'debug_mode' => true,
'debug_file' => APPPATH . 'logs/' . date('Y-m-d') . '.log',
], //To populate in a similar way to Twitter
'Facebook' => [
'enabled' => true,
'keys' => [
'id' => '...',
'secret' => '...'
],
'debug_mode' => true,
'debug_file' => APPPATH . 'logs/' . date('Y-m-d') . '.log',
],
'LinkedIn' => [
'enabled' => true,
'keys' => [
'id' => '...',
'secret' => '...'
],
'debug_mode' => true,
'debug_file' => APPPATH . 'logs/' . date('Y-m-d') . '.log',
],
]
];
Here is the implementation of hybridauth
public function social_auth()
{
$user_profile = NULL;
$auth_provider = $this->input->get('auth_provider');
// Check if it is redirected url with code & state params
if (!isset($_GET['code'])) {
$user_role = $this->input->get('role');
// Save it in the session to reuse it after auth redirect
// We'll need it in case user does not exist
$_SESSION['temp_user_role'] = $user_role;
}
switch ($auth_provider) {
case GOOGLE:
$auth_provider = GOOGLE;
break;
case FACEBOOK:
$auth_provider = FACEBOOK;
break;
case LINKEDIN:
$auth_provider = LINKEDIN;
break;
default:
$auth_provider = GOOGLE;
break;
}
// Load the hybridauth config file
$this->config->load('hybridauth');
//First step is to build a configuration array to pass to `Hybridauth\Hybridauth`
$config = $this->config->item('hybridauth');
try {
//Feed configuration array to Hybridauth
$hybridauth = new Hybridauth($config);
//Attempt to authenticate users with a provider by name
$adapter = $hybridauth->authenticate($auth_provider);
//Retrieve the user's profile
$user_profile = $adapter->getUserProfile();
//Disconnect the adapter
$adapter->disconnect();
} catch (\Exception $e) {
echo 'Oops, we ran into an issue! ' . $e->getMessage();
}
if (!empty($user_profile)) {
$email = $user_profile->email;
// Check if email exist in DB then sign in the user
$user_data = $this->User_model->find(['email' => $email], USERS);
if (!empty($user_data) && count($user_data) > 0) {
$user = $user_data[0];
$user_role = "";
// Cross check the user role
$user_groups = $this->ion_auth->get_users_groups($user->id)->result();
if (!empty($user_groups)) {
$group = $user_groups[0];
switch ($group->id) {
case ROLE_INDIVIDUAL:
$user_role = ROLE_INDIVIDUAL_STRING;
break;
case ROLE_COMPANY:
$user_role = ROLE_COMPANY_STRING;
break;
}
} else {
// Something went wrong, Force logout user
redirect('auth/logout');
}
if (empty($user_role)) {
redirect('auth/logout');
}
// Explicitly set the user role here
// coz it required in header's menubar
$user->role = $user_role;
$login_done = $this->ion_auth->set_session($user);
if ($login_done == TRUE) {
// Everything is OK, redirect the user to home page
redirect('/');
} else {
echo "We could not logged you in this moment!Please try after some time.";
}
} else {
$this->create_user_via_social_sign_up($user_profile);
}
} else {
echo "Unable to get your data!Try after some time.";
}
}
private function create_user_via_social_sign_up($user_profile)
{
$user_role = check_group($_SESSION['temp_user_role']);
if (empty($user_profile) or empty($user_role)) {
// Something went wrong, Force logout user
redirect('auth/logout');
}
$email = $user_profile->email;
// Generate a random password,
$password = substr(md5(rand()), 0, 7);
$extra_data = [
'active' => 1,
'is_approved' => 1
];
$this->db->trans_start();
// Directly register user via Model method as no need to send the activation email
$id = $this->ion_auth_model->register($email, $password, $email, $extra_data, [$user_role]);
$user_data = $this->User_model->find(['id' => $id], USERS);
$user = $user_data[0];
// Add the role in user object
$user->role = $user_role;
$redirectProfileUrl = base_url('Profile_setting/');
if ($this->ion_auth->set_session($user)) {
// Create empty records in tables
$this->User_model->create_user_entries($user->id, $user_role);
if ($this->db->trans_status() !== false) {
$this->db->trans_commit();
redirect($redirectProfileUrl);
} else {
// Something went wrong rollback all the transactions & inform the user
$this->db->trans_rollback();
echo "Our system is down right now!Please try after some time.";
}
}
}
Codeigniter version: 3.x
Hybridauth Version: 3

How fix Facebook login error in codeigniter

Facebook SDK returned an error:
Cross-site request forgery validation failed. The "state" param from the URL and session do not match.
I use fblogin() and fbcallback() in same controller. But face this error. Also do all steps in developer.facebook.com. Session is also started. But error says, do not match.
public function fblogin(){
$this->load->library('session');
$this->load->view('../libraries/facebook-php-sdk/src/Facebook/autoload.php');
$fb = new Facebook\Facebook([
'app_id' => 'APP_ID', // Replace {app-id} with your app id
'app_secret' => '{APP_SECRET}',
'default_graph_version' => 'v2.5',//v2.5
]);
$helper = $fb->getRedirectLoginHelper();
// if (isset($_GET['state'])) {
// $helper->getPersistentDataHandler()->set('state', $_GET['state']);
// }
// $sURL = $helper->getLoginUrl(FACEBOOK_AUTH_CALLBACK, FACEBOOK_PERMISSIONS);
$permissions = ['email']; // Optional permissions
$loginUrl = $helper->getLoginUrl('https://www.collegeprintsusa.com/maintenance/signin/fbcallback', $permissions);
// echo 'Log in with Facebook!';
header("location: ".$loginUrl);
}
public function fbcallback() {
$this->load->view('../libraries/facebook-php-sdk/src/Facebook/autoload.php');
$fb = new Facebook\Facebook([
'app_id' => 'APP_ID',
'app_secret' => 'APP_SECRET',
'default_graph_version' => 'v2.5',//v2.5
]);
// $serializedFacebookApp = serialize($fb);
// $unserializedFacebookApp = unserialize($serializedFacebookApp);
// echo $unserializedFacebookApp->getAccessToken();
$helper = $fb->getRedirectLoginHelper(); //'https://www.collegeprintsusa.com/maintenance/signin/fblogin'
// $_SESSION['FBRLH_state'] = $_REQUEST['state'];
$permissions = ['email']; // optional
try {
if (isset($_SESSION['facebook_access_token'])) {
$accessToken = $_SESSION['facebook_access_token'];
} else {
$fbClient = $fb->getClient();
$accessToken = $helper->getAccessToken($fbClient);
}
} catch(Facebook\Exceptions\facebookResponseException $e) {
// When Graph returns an error
echo 'Graph returned an error: ' . $e->getMessage();
exit;
} catch(Facebook\Exceptions\FacebookSDKException $e) {
// When validation fails or other local issues
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}
if (isset($accessToken)) {
if (isset($_SESSION['facebook_access_token'])) {
$fb->setDefaultAccessToken($_SESSION['facebook_access_token']);
} else {
// getting short-lived access token
$_SESSION['facebook_access_token'] = (string) $accessToken;
// OAuth 2.0 client handler
$oAuth2Client = $fb->getOAuth2Client();
// Exchanges a short-lived access token for a long-lived one
$longLivedAccessToken = $oAuth2Client->getLongLivedAccessToken($_SESSION['facebook_access_token']);
$_SESSION['facebook_access_token'] = (string) $longLivedAccessToken;
// setting default access token to be used in script
$fb->setDefaultAccessToken($_SESSION['facebook_access_token']);
}
// redirect the user to the profile page if it has "code" GET variable
if (isset($_GET['code'])) {
header('Location: collegeprintsusa.com');
}
// getting basic info about user
try {
$profile_request = $fb->get('/me?fields=name,first_name,last_name,email', $accessToken);
$requestPicture = $fb->get('/me/picture?redirect=false&height=200'); //getting user picture
$picture = $requestPicture->getGraphUser();
$profile = $profile_request->getGraphUser();
$fbid = $profile->getProperty('id'); // To Get Facebook ID
$fbfullname = $profile->getProperty('name'); // To Get Facebook full name
$fbemail = $profile->getProperty('email'); // To Get Facebook email
$fbpic = "<img src='".$picture['url']."' class='img-rounded'/>";
// echo $fbid.','.$fbfullname; die();
# save the user nformation in session variable
$get_user_email = $this->user_model->get_single_user(['email' => $fbemail]);
if($get_user_email){
$res_user_fbid_update = $this->user_model->update_users(['id' => $get_user_email['id']],['facebook_id' => $fbid]);
if($res_user_fbid_update){
$this->session->set_userdata(['username' => $get_user_email['usename'],
'name' => $get_user_email['name'],
'last' => $get_user_email['last_name'],
'email' => $get_user_email['email'],
'type' => $get_user_email['user_type'],
'uid' => $get_user_email['id'],
'phone' => $get_user_email['phone'],
'address' => $get_user_email['address'],
'profile_image' => $get_user_email['profile_image'],
'disable' => $get_user_email['sms_update']]);
$this->output->set_output(json_encode(['result' => 1]));
return FALSE;
}else{
$this->output->set_output(json_encode(['result' => 2]));
return FALSE;
}
}else{
$res_user_reg = $this->user_model->add_users([
'name' => $fbfullname,
'email' => $fbemail,
'phone' => 0,
'user_type' => 'customer',
'username' => $fbemail,
'password' => SALT . sha1($fbemail),
'token' => SALT . sha1($fbemail),
'facebook_id' => $fbid
]);
if($res_user_reg){
$this->output->set_output(json_encode(['result' => 1]));
return FALSE;
}else{
$this->output->set_output(json_encode(['result' => 2]));
return FALSE;
}
}
} catch(Facebook\Exceptions\FacebookResponseException $e) {
// When Graph returns an error
echo 'Graph returned an error: ' . $e->getMessage();
session_destroy();
// redirecting user back to app login page
header("Location: index.php");
exit;
} catch(Facebook\Exceptions\FacebookSDKException $e) {
// When validation fails or other local issues
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}
} else {
// replace your website URL same as added in the developers.Facebook.com/apps e.g. if you used http instead of https and you used
$loginUrl = $helper->getLoginUrl('http://phpstack-21306-56790-161818.cloudwaysapps.com', $permissions);
echo 'Log in with Facebook!';
}
}
Here I would like to suggest a better solution to log in with Facebook. Please use JavaScript instead of PHP, because PHP will redirect on facebook page & JavaScript will not redirect, It will open facebook login popup on own website, and it`s very quick & easy process according to performance.
Please follow below code to login with facebook using JavaScript.
$(document).ready(function($) {
window.fbAsyncInit = function() {
FB.init({
appId : '186770818730407', // Set YOUR APP ID
status : true, // check login status
cookie : true, // enable cookies to allow the server to access the session
xfbml : true // parse XFBML
});
};
function fbLogin()
{
FB.login(function(response) {
if (response.authResponse) {
getFBUserInfo();
}else {
showToaster('error','User cancelled login or did not fully authorize.');
return false;
}
},{scope: 'email,user_photos,user_videos'});
}
function getFBUserInfo() {
FB.api('/me',{fields: "id,picture,email,first_name,gender,middle_name,name"}, function(response) {
$.ajax({
url : "http://example.com/welcome/facebook_login",
type : "POST",
data : {response:response},
dataType : "JSON",
beforeSend:function(){
ajaxindicatorstart();
},
success: function(resp){
ajaxindicatorstop();
if(resp.type == "success"){
fbLogout();
showToaster('success',resp.msg);
setTimeout(function(){
window.location.href = base_url() + 'account-setting';
},1000);
}
else{
showToaster('error',resp.msg);
}
},
error:function(error)
{
ajaxindicatorstop();
}
});
});
}
function fbLogout()
{
FB.logout(function(){ console.log('facebook logout') });
}
// Load the SDK asynchronously
(function(d){
var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];
if (d.getElementById(id)) {return;}
js = d.createElement('script'); js.id = id; js.async = true;
js.src = "//connect.facebook.net/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
});
Hope You will like it.
Thanks

laravel on saving model return json from validation

Hi I'm having a problem outputting my json information on saving method in the model. I get the following error -
UnexpectedValueException in Response.php line 397:
The Response content must be a string or object implementing __toString(), "boolean" given.
I do validation on the model while saving and in the validate method of the model I need to out put the json but I'm getting boolean instead of json object
Javascript:
submit: function(e) {
e.preventDefault();
var contact = this.model.save({
firstname: this.firstname.val(),
lastname: this.lastname.val(),
company: this.company.val(),
email_address: this.email_address.val(),
description: this.description.val(),
}, {success:function(response){ console.log(response)}, wait: true});
Contact Model:
class Contact extends Model
{
protected $table = "contacts";
protected $fillable = ['firstname', 'lastname', 'company', 'email_address', 'description'];
public static function boot() {
parent::boot();
static::creating(function($model) {
return $model->validate('POST');
});
static::updating(function($model) {
return $model->validate('PUT');
});
static::saving(function($model) {
return $model->validate('PUT');
});
}
public function rules($method)
{
switch($method)
{
case 'GET':
case 'DELETE':
{
return [];
}
case 'POST':
{
return [
'firstname' => 'required',
'lastname' => 'required',
'email_address' => 'required|email|unique:contacts,email_address',
'description' => 'requried'
];
}
case 'PUT':
case 'PATCH':
{
return [
'firstname' => 'required',
'lastname' => 'required',
'email_address' => 'required|email|unique:contacts,email_address,'.$this->id,
'description' => 'required',
];
}
default: break;
}
return [];
}
public function messages() {
return [
'firstname.required' => 'Please enter your first name.',
'lastname.required' => 'Please enter your first name.',
'email_address.required' => 'Please enter a email address.',
'email_address.email' => 'Please enter a valid email address',
'email_address.unique' => 'The email is not unique.',
'description' => 'Please enter a description.'
];
}
public function validate($method)
{
$data = $this->attributes;
// if( $data['slug'] === '') {
// // if the slug is blank, create one from title data
// $data['slug'] = str_slug( $data['title'], '-' );
// }
// make a new validator object
$v = Validator::make($data, $this->rules($method), $this->messages());
// check for failure
if ($v->fails())
{
// set errors and return false
// json here not return response it's always boolean true or false
return new JsonResponse(array('error' => true, 'errors' => $v->messages()));
}
// validation pass
return true; //new JsonResponse(array('errors'=>false));
}
public function errors() {
return $this->errors;
}
public function user() {
return $this->hasOne('App\User', 'email', 'email_address');
}
}
Saving the model:
public function update(Request $request, $id) {
$contact = Contact::find($id)->with('user')->first();
$contact->firstname = $request->get('firstname');
$contact->lastname = $request->get('lastname');
$contact->email_address = $request->get('email_address');
$contact->company = $request->get('company');
$contact->description = $request->get('description');
return $contact->save(); //return formatted json
}
According to your implementation of validation, you should change the following part (in Contact):
// check for failure
if ($v->fails())
{
// set errors and return false
// json here not return response it's always boolean true or false
return new JsonResponse(array('error' => true, 'errors' => $v->messages()));
}
To something like this:
if ($v->fails()) {
$this->errors = $v->errors();
return false;
}
Then, from the Controller, try something like this:
// If validation failed
if(!$contact->save()) {
return response()->json([
'error' => true,
'errors' => $contact->errors()
]);
}
// Contact created if reached here...
return response()->json(['error' => false, 'contact' => $contact]);
Also, check the Ajax-Request-Validation and Form-Request-Validation (Easier and Managable).
Note: Don't try to return any kind of HTTP Response from model. Returning the HTTP response is part of your application logic and model should not care about these.
As save() does return boolean so You've to check if it's ok.
1) Change Your Contact model to put errors to model's errors param:
/* if($v->fails()) remove/comment this line
...
} */
$this->errors = $v->errors();
return !$v->fails();
2) In Your controller put this code:
public function update(Request $request, $id) {
$contact = Contact::find($id)->with('user')->first();
if(!$contact) {
return response('Contact not found', 404);
}
$contact->firstname = $request->get('firstname');
$contact->lastname = $request->get('lastname');
$contact->email_address = $request->get('email_address');
$contact->company = $request->get('company');
$contact->description = $request->get('description');
return $contact->save()?
$contact->toJson() : // returns 200 OK status with contact (json)
response($contact->errors, 400); // returns proper 400 Bad Request header with errors (json) in it
}
p.s. it's nice to answer to requester with http status, industry has made all to make life of developer easy, so if it's not 2xx, 3xx status so => response for Your request from client-side app will be treated as error (handler success: function(response) will not catch error here)

CakePHP login when trying to acces controller

im having troubles with a web app that a teacher ask me to modify, the problem its that i dont know about cakePHP and i have been having troubles.After reading a lot, i think i have grasped the basics of the framework. My problem now its that i have a link in a view so i call a function in the controller to retrive data from the model, the problem its that each time i try to acces the function , the app makes me log in, and the idea its that it shouldnt.
I dont know exactly how the session handling on cakePhp works so, im requesting some help.
the code for the controller its this:
<?php
class RwController extends AppController {
var $name = 'Rw';
// var $paginate = array(
// 'Tip' => array(
// 'limit' => 1,
// 'order' => array(
// 'tip.created' => 'desc'
// ),
// ),
// 'Evento' => array(
// 'limit' => 1,
// 'order' => array(
// 'evento.fecha' => 'desc'
// ),
// )
// );
function map() {
$this->helpers[]='GoogleMapV3';
}
function pageForPagination($model) {
$page = 1;
// $chars = preg_split('/model:/', $this->params['url']['url'], -1, PREG_SPLIT_OFFSET_CAPTURE);
// #print_r($chars);
// if(sizeof($chars) > 1 && sizeof($chars) < 3) {
// #echo "Belongs to ".$model.": \n";
// #echo var_dump($chars);
// }
// $params = Dispatcher::parseParams(Dispatcher::uri());
// echo "<p>".var_dump($params)."</p><br />";
#echo $this->params['named']['model'].$model;
#echo $this->params['named']['page'];
$sameModel = isset($this->params['named']['model']) && $this->params['named']['model'] == $model;
$pageInUrl = isset($this->params['named']['page']);
if ($sameModel && $pageInUrl) {
$page = $this->params['named']['page'];
} else {
#echo var_dump($this->passedArgs);
}
$this->passedArgs['page'] = $page;
return $page;
}
function index() {
$this->log('indexeando esta chingadera','debug');
$this->loadModel('User');
$this->loadModel('Evento');
$this->loadModel('Tip');
$dataEvento = $this->Evento->find('all');
$dataTip = $this->Tip->find('all');
$page = $this->pageForPagination('Evento');
$this->paginate['Evento'] = array(
'contain' => false,
'order' => array('Evento.fecha' => 'desc'),
'limit' => 1,
'page' => $page
);
$dataEvento = $this->paginate('Evento');
$page = $this->pageForPagination('Tip');
$this->paginate['Tip'] = array(
'contain' => false,
'order' => array('Tip.created' => 'desc'),
'limit' => 1,
'page' => $page
);
$dataTip = $this->paginate('Tip');
$this->set('users', $this->User->find('all'));
$this->set('eventos', $dataEvento);
$this->set('tips', $dataTip);
$this->set('rw');
if(isset($this->params['named']['model'])) {
if (strcmp($this->params['named']['model'], 'Evento') == 0) {
if($this->RequestHandler->isAjax()) {
$this->render('/elements/ajax_rw_evento_paginate');
return;
}
} elseif (strcmp($this->params['named']['model'], 'Tip') == 0) {
if($this->RequestHandler->isAjax()) {
$this->render('/elements/ajax_rw_tip_paginate');
return;
}
}
}
}
function about($id = null) {
$this->Rw->recursive = 0;
$this->set('rw', $this->paginate());
}
function beforeFilter() {
parent::beforeFilter();
$this->Auth->allow(array('index', 'about'));
}
function getCentros($id){
$this->loadModel('Centro');
$this->log('getcentros','debug');
if( sizeof($id) > 1){
$this->set('centros', $this->Centro->query("SELECT centros.id, name, latitud ,longitud
FROM `centros`,`centrosmateriales`
WHERE centros.id = centro_id
AND material_id ='".$id[0]."'
OR material_id='".$id[1]."'"));
}elseif( sizeof($id) >0) {
if($id == 0){
$this->set('centros', $this->Centro->find('all'));
}else{
$this->set('centros', $this->Centro->query("SELECT centros.id, name, latitud ,longitud
FROM `centros`,`centrosmateriales`
WHERE centros.id = centro_id
AND material_id ='".$id[0]."'"));
}
}
$this->redirect(array('action' => 'index'));
}
}
?>
Edit:
The function im calling is getCentros().
this is what i have in app_controller.
<?php
class AppController extends Controller {
var $components = array('Session', 'Auth', 'RequestHandler');
var $helpers = array('Html', 'Form', 'Time', 'Session', 'Js', 'Paginator', 'GoogleMapV3');
function beforeFilter() {
$this->Auth->userModel = 'User';
$this->Auth->fields = array('username' => 'email', 'password' => 'password');
$this->Auth->loginAction = array('admin' => false, 'controller' => 'users', 'action' => 'login');
$this->Auth->loginRedirect = array('controller' => 'users', 'action' => 'index');
}
}
?>
try this
$this->Auth->allow(array('*'));
it allows you to access all functions inside the controller.
But before that make sure that you have access on the controller with out errors because your controller name is like this
class RwController extends AppController {
}
may be it want like this
class RwsController extends AppController {
}
Don't know which function you are trying to call but if cake tries to log you in and you don'want this add the function to:
$this->Auth->allow(array('index', 'about'));
in your beforefilter

Resources