Sample for Edit Url for a FB Page Tab App - facebook-iframe

I am implementing the edit url FB Page Tab App. But it needs the initialization which should happen when the app is added to a fanpage by the admin.
I am looking for the initial callback/notification to my app-url when the app is loaded on the fanpage. (I have looked at this already - http://developers.facebook.com/docs/authentication/signed_request/).
I am looking for a sample that shows the handling of the signed_request in this case, from the fan-page-load and what details are available/etc..
Thanks !

Here's a sample of handling the signed request:
function parse_signed_request($signed_request, $secret) {
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
// decode the data
$sig = base64_url_decode($encoded_sig);
$data = json_decode(base64_url_decode($payload), true);
if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') {
error_log('Unknown algorithm. Expected HMAC-SHA256');
return null;
}
// check sig
$expected_sig = hash_hmac('sha256', $payload, $secret, $raw = true);
if ($sig !== $expected_sig) {
error_log('Bad Signed JSON signature!');
return null;
}
return $data;
}
function base64_url_decode($input) {
return base64_decode(strtr($input, '-_', '+/'));
}
in $data there will be a "page" object that has a "admin" boolean. This will tell you if the current user of the page tab application is an admin of the page that the app is a tab of.

Related

Maintaining a Session in MVC .net application using angularjs

I am working on an application, in which a user if has an account in db can log in the website and then perform certain functions. One of those functions involve creating a blog. The blog is being displayed in another project application using the same database. Now when user creates a blog after logging in, i need to store who created the blog in order to do that, i came up with 2 ways. Either i keep passing the user id as a parameter on every page url or i can create a session in order to store it for the duration of login.
I think the latter is a better option but i am kind of lost on how to do it. I am creating a 3 project layer Application. with the client side done in angularjs. My c# controller is being used just to pass the json data to another layer, which then communicates with the database which is in another layer.
The project files are too big but i can write a example code for it.
Html:
<div ng-app="Module">
<div ng-controller="AppController">
<input ng-model="user.Email" type="email"\>
<button type="button" ng-click="UserLogin()"\>
</div>
</div>
AngualrJs:
var app = angular.module('Module', []);
app.controller("AppController", function ($scope) {
$scope.loginchk = function () {
Post("/User/LoginValidation", $scope.user, false, $("#btnlogin")).then(function (d) {
if (d.Success) {
window.location.href = "/User/LoggedIn?emailId=" + $scope.user.Email;
}
ShowMessage(d);
});
}
})
Controller:
public JsonResult LoginValidation(LoginUser user) {
return Json((new userLogic()).LoginChk(user), JsonRequestBehavior.AllowGet);
}
Business Logic LAYER----------------
UserLogic:
public Message LoginChk(LoginUser user) {
Message msg = new Message();
try {
Account userProfile = db.Accounts.Where(b => b.Email == user.Email).FirstOrDefault();
if (userProfile == null)
{
msg.Success = false;
msg.MessageDetail = "Account Email does not exist";
}
else
{
if (userProfile.password != user.Password)
{
msg.Success = false;
msg.MessageDetail = "Wrong Password";
}
else
{
msg.Success = true;
msg.MessageDetail = "Logged In";
}
}
}
catch(Exception ex)
{
msg.Success = false;
msg.MessageDetail = "DB connection failed.";
}
return msg;
}
Now I know i can create a Session Variable in the controller like this Session['Sessionname'] = user;
but i am not sure it will work with my application because i have multiple controllers and i will still have to pass it to them. so i dont see the point of maintaining a session variable in every controller even if its not used. How do i go about creating a session?
local storage is best option to do that :
window.localStorage.setItem("userId",useId);
to get again:
localStorage.getItem("userId");
You Can use client-side LocalStorage to save the user-id and use it where ever necessary,
as it will be saved in plain text you can encrypt and save it .
check here how to encrypt using javascript
https://stackoverflow.com/a/40478682/7262120

GetExternalLoginInfoAsync return null value

I am working on MVC core 2 and IdentityServer4, External user logged in successfully, the problem i'm facing is this function always return null in HomeController.
var info = await _signInManager.GetExternalLoginInfoAsync();
But its working in AccountController, when user login and redirected back to client from IdentityServer.
public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null, string remoteError = null)
{
var info = await _signInManager.GetExternalLoginInfoAsync();
}
Any kind of help will be appreciated.
My issue was in SignInScheme. When I commented the line below in Startup and use defaults it started to work.
services.AddAuthentication().AddGoogle("Google", opt =>
{
//opt.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
...
}
It's all based on cookies so check that the cookie is being picked up correctly. I think be default it will set the path of the cookie and that may mean it is not sent to your AccountController because the path differs.

Implementation of Paypal in single page application

I am currently working on a game, which will consist out of an API-based backend, along with a web frontend (which is a single page app, in AngularJS) and on several mobile devices (using Cordova). I am planning on serving the SPA over the main domain name, along with a CDN. The SPA (and homepage) will all be static HTML/Javascript/CSS files, so the only part which is dynamic is the api. The domain name for the "main server" hosting the static sites will be in the style of example.com, the one for the api will be api.example.com
I am wondering how I can integrate Paypal into this scenario though. The internet doesn't seem to offer much advice on how to integrate it into S.P.A's like this...or my google-fu could be off. Thanks for the replies.
Below is how I am handling the situation,
I have a button to say pay with paypal and onClick I open a new window -> window.open("/paypalCreate", width = "20px", height = "20px");
and I capture this get request "/paypalCreate" in my node.js server and call create method which looks liek below
exports.create = function (req, res) {
//Payment object
var payment = {
//fill details from DB
};
//Passing the payment over to PayPal
paypal.payment.create(payment, function (error, payment) {
if (error) {
console.log(error);
} else {
if (payment.payer.payment_method === 'paypal') {
req.session.paymentId = payment.id;
var redirectUrl;
for (var i = 0; i < payment.links.length; i++) {
var link = payment.links[i];
if (link.method === 'REDIRECT') {
redirectUrl = link.href;
}
}
res.redirect(redirectUrl);
}
}
});
};
This redirects user to paypal and once user confirms or cancels payment, the redirect urls are called. And in the success redirect url I capture the payment details into the databse and render a html in this opened window with the confirmation.
exports.execute = function (req, res) {
var paymentId = req.session.paymentId;
var payerId = req.param('PayerID');
// 1. if this is executed, then that means the payment was successful, now store the paymentId, payerId and token into the database
// 2. At the close of the popup window open a confirmation for the reserved listing
var details = {"payer_id": payerId};
paypal.payment.execute(paymentId, details, function (error, payment) {
if (error) {
console.log(error);
} else {
//res.send("Hell yeah!");
res.render('paypalSuccess', {payerId: payerId, paymentId: paymentId});
}
});
};
Once the user closes the opened window in which paypal was being handled the orginal SPA window will be refreshed and thus getting the payment details from the DB and here you can handle the SPA in whatever way you want.
I know that this is a dirty hack, but like you I couldnt find a better way. Please let me know if this works for you or if you have a found a better way to do tihs.
cheers,
Chidan

Redirect to the last page requested after login in cakephp

HI I have search from where client can either click on keywords
which is below in search bar or enter a keyword in search window, In
case first when user click on keywords the search_results opens with
keywords in URL but when user enter keyword then it just give result
according to it.
So when user not logged in then after some search_result we ask for
login & on click login button we redirect for login popup from where
user logged in that time we have to redirect on same page so for
this I am using two concept one for predefined keywords link which
come on URL just redirect last URL value in session & after logged
in redirect to that URL.
3.I need help in keyword enter by user & then logged in so needs to redirect with same keyword page to user.
function search_result($adKeyword = null){
if(!empty($adKeyword) && $adKeyword != ''){
$this->data['City']['keyword'] = $adKeyword;
}
//////////////////Maintain fetch data////////////////////
if(!empty($this->data)){
//pr($this->data);exit;
if($this->data['City']['keyword'] == 'Name or Area of expertise'){
$this->data['City']['keyword'] = '';
$this->set("title_for_layout","Search Result");
}
if ( empty($this->data['City']['city_name'])) {
$this->data['City']['city_name'] = $this->Session->read("Location");
}
if($this->data['City']['keyword'] != '')
$this->set("title_for_layout",$this->data['City']['keyword']." | Search Result");
//$request_params = Router::getParams();
//$this->Session->write('auth_redirect','/'.$request_params['url']['url']);
$this->Session->write('login_referrer',$this->params['url']['url']);
$this->Session->write('login_referrers',$this->data['City']['keyword']);
above two session variable I am using for redirect after authentication on login
if($this->Auth->user('role_id')== Configure::read('App.Role.Mentee')) {
if ($this->Session->check('login_referrer')) {
$loginReferrer = $this->Session->read('login_referrer');
$this->Session->delete('login_referrer');
//prd($loginReferrer);
$this->redirect(SITE_URL."$loginReferrer");
}
else if($this->Session->check('login_referrers'))
{
$loginReferrers = $this->Session->read('login_referrers');
$this->Session->delete('login_referrers');
//prd($loginReferrers);
$this->redirect(array('controller'=>'fronts','action'=>'search_result/','$adKeyword' => $loginReferrers));
}
else {
$this->redirect(array('controller'=>'fronts','action'=>'index'));
}
what happening its not going to else if statement Please help me
If they are browsing some pages and asked to login then they should redirect to that page after login
That's exactly what the Auth component does by default. As such to get the desired behavior, the login function should look similar to:
public function login() {
if ($this->request->is('post')) {
if ($this->Auth->login()) {
return $this->redirect($this->Auth->redirect());
}
$this->Session->setFlash(__('Invalid username or password, try again'));
}
}
Note the use of $this->Auth->redirect() which returns the url to redirect the user to, this example is taken directly from the documentation.
To change the default Auth redirect url modify the loginRedirect property of the auth component (from your beforeFilter, for example).
For manually login I have solved my issue,I have added this code to search_result action of my front_controller
$request_params = Router::getParams();
$this->Session->write('auth_redirect','/'.$request_params['url']['url']);
And in my user _controller I have just used this session variable:
if($this->Auth->user('role_id')== Configure::read('App.Role.Mentee')) {
$this->redirect($this->Session->read('auth_redirect'));
else
$this->redirect(array('controller'=>'fronts','action'=>'index'));
But it is not solving my problem completely, I want to delete session value after one time redirect.but for this it is not destroying the router session variable value

webtechnick Facebook logout not working

I am using webtechnick facebook plugin, i have everything set and its FB login works perfectly.
I am using $fbc =$this->Connect->User(); to fetch FB details of logged in user
And using
<?php
echo $facebook->login(array('perms' => 'email,publish_stream','size'=>'small'));
?>
<?php
echo $this->Facebook->logout();
?>
for login,logout respectively. i am getting details of user after login, but it will not unset after performing a logout();
I am using webtechnick fb plugin version 3.1.1 . Please help me
My help isn't much help because I haven't really found a solution. The good news is that you are not alone:
https://github.com/webtechnick/CakePHP-Facebook-Plugin/issues/43
What I can tell you is that the facebook cookie (fbsr_{facebook_app_id}) is either not deleting or is being recreated and that is the root of the problem.
EDIT
I may have found out what's going on here. Until the other night I had not bothered to setup my .htaccess files and both http:/www.example.com and http:/example.com were valid.
In my facebook app, I had set up example.com as a domain and pointed the site URL to www.example.com.
With the fbsr_{app id} cookie, I noticed that it was sometimes on the http://example.com while my cakephp cookies were on www.
I played around with changing the URL in my facebook app (adding www, removing www) and then also started doing the rewrite rules in .htaccess to add or remove www. I just removed the appdomain entirely from my facebook app, forced www. to the domain, and now everything is kosher.
So I think the trick is to
Not have the app domain in the facebook app
Fix canonicalization of www via .htaccess
This ensures that both the cakephp and the facebook cookies are being saved to the identical domain, and when you logout they are removed from said domain.
Hope this makes sense...
I know it is too late for some suggestion for this post. Still feel it might help some one who later reading this post.
I too was facing the logout issue with the plugin , I have modified a function in ConnectComponent in the plugin to clear its session details if the action is "logout". Below is the modified function :
private function __syncFacebookUser(){
if($this->Controller->params['action'] == 'logout')
{
$this->Controller->Session->delete('FB');
$this->uid = null;
$this->Controller->Session->delete('Auth.User');
}
else
{
if(!isset($this->Controller->Auth)){
return false;
}
$Auth = $this->Controller->Auth;
if (!$this->__initUserModel()) {
return false;
}
// if you don't have a facebook_id field in your user table, throw an error
if(!$this->User->hasField('facebook_id')){
$this->__error("Facebook.Connect handleFacebookUser Error. facebook_id not found in {$Auth->userModel} table.");
return false;
}
// check if the user already has an account
// User is logged in but doesn't have a
if($Auth->user('id')){
$this->hasAccount = true;
$this->User->id = $Auth->user($this->User->primaryKey);
if (!$this->User->field('facebook_id')) {
$this->User->saveField('facebook_id', $this->uid);
}
return true;
}
else {
// attempt to find the user by their facebook id
$this->authUser = $this->User->findByFacebookId($this->uid);
//if we have a user, set hasAccount
if(!empty($this->authUser)){
$this->hasAccount = true;
}
//create the user if we don't have one
elseif(empty($this->authUser) && $this->createUser) {
$this->authUser[$this->User->alias]['facebook_id'] = $this->uid;
$this->authUser[$this->User->alias][$this->modelFields['password']] = $Auth->password(FacebookInfo::randPass());
if($this->__runCallback('beforeFacebookSave')){
$this->hasAccount = ($this->User->save($this->authUser, array('validate' => false)));
}
else {
$this->authUser = null;
}
}
//Login user if we have one
if($this->authUser){
$this->__runCallback('beforeFacebookLogin', $this->authUser);
$Auth->authenticate = array(
'Form' => array(
'fields' => array('username' => 'facebook_id', 'password' => $this->modelFields['password'])
)
);
if($Auth->login($this->authUser[$this->model])){
$this->__runCallback('afterFacebookLogin');
}
}
return true;
}
}
}
For me now the facebook plugin is working fine for facebook connect.

Resources