I'm writing an app written in C# - Xamarin Forms.
I'm simply trying to get a response from Braintree's server so I can process payment.
This response is the payment_method_nonce which is required to process payment.
Here's the client side code provided by Braintree.
<script src="https://js.braintreegateway.com/web/dropin/1.24.0/js/dropin.js"></script>
<div id="dropin-container"></div>
<button id="submit-button" class="button button--small button--green">Purchase</button>
var button = document.querySelector('#submit-button');
braintree.dropin.create({
authorization: 'xxxxx',
selector: '#dropin-container'
}, function (err, instance) {
button.addEventListener('click', function () {
instance.requestPaymentMethod(function (err, payload) {
// Submit payload.nonce to your server
});
})
});
It generates the credit card form nicely however if you click on the Purchase button, a payment_method_nonce is expected to return from the Braintree server.
My question is, how do I capture this payment_method_nonce variable in C# when the client form is rendered in Javascript, inside a webview?
Got it working.
You have to get the payment method token first after you've processed the credit card details.
Then pass this method payment token to get the payment method nonce then you proceed with the transaction.
Here's the code:
// Get the payment method token
var paymentmethod_token = creditCard.Token.ToString();
// Generate a payment method nonce
Result<PaymentMethodNonce> paymentmethodnonce_result = gateway.PaymentMethodNonce.Create(paymentmethod_token);
var nonce = paymentmethodnonce_result.Target.Nonce;
Related
I'm migrating from the old Google Sign In library to the new Google Identity Services (GIS) library. This is mandatory, since the old one will no longer be in use from March 2023.
Previously, I did (simplified for clarity):
<script src="https://apis.google.com/js/api:client.js"></script>
gapi.load();
var auth2 = gapi.auth2.init();
auth2.attachClickHandler();
onGoogleSignIn(googleUser); // attachClickHandler's callback
var profile = googleUser.getBasicProfile(); // profile info accessible
var authResponse = googleUser.getAuthResponse(); // auth response accessible
var accessToken = authResponse.id_token; // get actual access token
Now, I'm trying (simplified for clarity):
<script src="https://accounts.google.com/gsi/client"></script>
var gisClient = google.accounts.oauth2.initTokenClient();
gisClient.requestAccessToken();
callback(); // initTokenClient's callback
var accessToken = response.access_token; // get access token in callback
With the old google sign in library, I validated the access token server side as such:
Payload payload = await GoogleJsonWebSignature.ValidateAsync(accessToken);
This also returned the user's email and name in the payload.
The access token I am getting back from GIS, is much shorter than the old one from GAPI.
An online token debugger tells me it's not a valid JWT token.
The ValidateAsync method throws an exception:
JWT must consist of Header, Payload, and Signature
No surprise, considering it's not a valid JWT token.
I also tried the following call:
Payload payload = await JsonWebSignature.VerifySignedTokenAsync(AccessToken, options);
Same result.
The official documentation doesn't say how to validate this token server side for C# / .NET.
I can't find help on this anywhere in the documentation.
What can I do to get server side access token validation (and retrieval of email + profile) working with Google Identity Services?
Explanation
The new Google Sign in returns "CredentialResponse"
which contains a property called credential, which is the JSON Web Token (JWT) in base64 that you need. This JWT can be sent to client or server for validation. After validation you will receive user profile data.
Client
<div id="g_id_onload"
data-client_id="YOUR_GOOGLE_CLIENT_ID"
data-callback="handleCredentialResponse">
</div>
<script>
function handleCredentialResponse(response) {
//get JSON Web Token (JWT) out of the response object
var jwt = response.credential;
//send JWT to backend server for validation
var result = ValidateAtServer(jwt);
//do something with result
KillUserInstantly(result);
}
</script>
Server (.NET)
public static void ValidateAtServer(httpRequest)
{
//get jwt string from request
...
//validate it using Google.Apis.Auth (null if invalid)
var validPayload = await GoogleJsonWebSignature.ValidateAsync(jwtToken);
//get user data & use it
var userId = validPayload.Subject; //The unique ID of the user's Google Account
var email = validPayload.Email;
//do something with data
...
}
Beginner Notes
"unique user ID" in located under subject or sub
"ID token" is the base64-encoded JSON Web Token (JWT) string.
Validating the JWT also decrypts the data inside which includes user profile.
Example JWT/ID Token
eyJhbGciOiJSUzI1NiIsImtpZCI6IjE1NDllMGFlZjU3NGQxYzdiZGQxMzZjMjAyYjhkMjkwNTgwYjE2NWMiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJuYmYiOjE2NTk3NTk0MzEsImF1ZCI6IjEwODgwNjIxNjM1NzMtaXMwdWQ1aDRza2JscmR1Njp0cnVlLCJheuZXMiLCJpYXQiOjE2NTk3NTk3MzEsImV4cCI6MTY1OTc2MzMzMSwianRpIjoiMDhlNjRhM2I1YzdmNzcxYmRjNTg5M2YwNmMyZjM1ZWZlMzIyNjYyMCJ9.UT07_-_4o_1D5NmVAI0QtXLupVZtXys3Kg0c--Cv-xrMpUZXInfqj142eojvTEf6QBmBPY3k-Mtu7djJAenB8Ed8-dWtvFdGdv5FdSJCSyLN70ObzCsdo_IgjG5r3HTw1C9pIFKggOklJrVN-zL0_Kh3TZdxfMdyEbAUuhIRCreUVgZ74XEWhR6x4l0EY9o2331HcrzAaie_LN4C8NVHhkQ0DLg5dO2v8T1uKG-eTyv-uvjMuhkSVBJR3MnvkGepj7o0h_ELGO9x74P9nNjIKTyZboEr4_YO0BP5aLPwt67LJHactAJ8DJTzugXwaJBVhusK1KPYYGRhy7nTfbfTSg
I have a C# ASP.NET MVC application. The application presents the user with a bootstrap styled login box. When the user enters his/her user ID and password, that information is passed to the Mainpage controller. The controller picks up the passed data and sends it to a custom build web service API. The API validates the passed user ID and password and if the validation is passed, the API returns basic login information regarding the user. The Mainpage controller takes that returned information, reformats it, and sends it along to a second custom web service API. This second API takes the passed data, retrieves the participant information from a master database, and sends back a response. The Mainpage controller then parses the response and populates a class and the class is passed to the view. The view displays the data. This all works as anticipated.
The question I have is in regard to the url that appears in the url box at the top of the browser. When the View displays the webpage, the url that displays in the url box at the top of the browser contains the data elements that were passes to the custom API. Here is a picture of the url box:
Obviously, I can not have user information showing in the url box.
How can I prevent the view from displaying this information? I have no problem showing localhost:5001/MainPage (localhost: as this is currently in development) but I can not have the parameter fields and the data passed in those fields displaying.
Thanks.
EDIT #1:
The code in my Mainpage controller builds a url string and uses the following code to send the data to the API:
public MQ mq6000Send(string passedMQMessage)
{
var mqResponseObject = new MQ();
var localAPIReturn = new APIReturn();
var url = "https://xxxxxxx-direct.com/api/homepage?mqRequest=" + passedMQMessage;
HttpClient client = new HttpClient();
var APIResponse = client.GetStringAsync(url).Result;
APIResponse = APIResponse.Substring(1, APIResponse.Length - 2);
APIReturn tempData = JsonConvert.DeserializeObject<APIReturn>(APIResponse);
mqResponseObject.MQResponse = tempData;
return mqResponseObject;
}
I came across few resources in internet where google authentication is done through web api.
So , I wanted to try the same in asp.net mvc web app in similar way.I am stuck in the middle on how to fetch the redirectUri for my application.
1.App is registered in google, clientid and secret is mentioned in Authconfig.cs.
2.Upon click of my button i have to redirect to GoogleSignIn page.The redirectUrl(authrequestUrl) which will take the user to signin page is something i am not getting.
In Web api,requesting below url(GET request) will return the redirectUrl as response.
http://localhost:xxxx/api/Account/ExternalLogin?returnUrl=%2f&generateState=true
which i can use for redirecting the user to google sign in page upon click of my sign in button from my Login View.
MyLogin.cshtml
<body>
<row>
<button id="GoogleBtn" type="button" class="col-md-5 btn">Google</button>
</row>
</body>
<script type="text/javascript">
$document.ready(function ()
{
$('#GoogleBtn').click(function ()
{
window.location.href="RedirectUrl"
});
});
</script>
In Asp.net MVc,
there exists two actions - external login and externallogincallback
Calling external login-
http://localhost:49837/Account/ExternalLogin?provider=Google&returnUrl=%2f
will return Error -'The required anti-forgery form field "__RequestVerificationToken" is not present.'
Calling externallogincallback-
http://localhost:49837/Account/ExternalLoginCallback?provider=Google&returnUrl=%2f&generateState=true
will redirect to another View (~/Views/Account/Login), where it contains a button for Google.
Upon clicking that button it takes me to Google SignInPage with all request parameters to process and sign in.
I want my app to redirect directly to Google SignIn page without going to account/login view and then being redirected to SignIn page upon clicking Google Button.
Someone help me in how to fetch the redirectUrl for my mvc application.
Update:
The Oauth request url/Google sign in request url is what i had been
looking for,I got confused with the redirectUrl. I found a way to
build the request Url and i successfully made the call using
javascript.
This code lets me make the Oauth request to Google SignIn page.
MyLogin.cshtml
<row>
<button id="GoogleBtn" type="button" class="col-md-5 btn btn-danger" onclick="googleLogin()">Google</button>
</row>
<script type="text/javascript">
var OAUTHURL = 'https://accounts.google.com/o/oauth2/auth?';
var VALIDURL = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=';
var SCOPE = 'https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email';
var CLIENTID = 'xxxxxxxxxxxmyclientidxxxxx.apps.googleusercontent.com';
var REDIRECT = 'http://myapp.local/dashboard';
var LOGOUT = 'http://myapp.local/logout';
var TYPE = 'token';
var _url = OAUTHURL + 'scope=' + SCOPE + '&client_id=' + CLIENTID + '&redirect_uri=' + REDIRECT + '&response_type=' + TYPE;
function googleLogin()
{
window.location = _url;
}
</script>
Hi you can access redirect url using below code
<script>
$(document).ready(function() {
if (location.hash) {
if (location.hash.split('access_token')) {
var access_Token = location.hash.split('access_token=')
[1].split('&')[0];
sessionStorage.setItem("access_Token", access_Token)
}
}
});
I have a problem implementing a Facebook Login on my ASP.NET website. I have both .NET Facebook SDK and the Javascript SDK installed in my site. I can't understand the flow that I need to implement in order to make it work.
In my app, I just need the email to register the user, give him the option to choose a username, and be able to login if he clicks the Facebook log in button (a custom one, it's not the official Facebook log in button).
I prefer a seamless login in which I get login the user via Ajax request to the server and set a cookie on the server instead of a redirect.
What is the registration and login flow that I need to implement to make it work using Ajax?
What I tried to do is to get the token on the client, but when I get the Token, I can't use it on the server, I need a code in order to get an active Token.
On my site I have both a custom Facebook signup and Facebook login buttons.
In my database I have the following columns for Facebook:
facebook_id
token
token_expiration
Here's the client code that I get the accessToken, userId and use it to get the user email:
function fb_login() {
FB.login(function (response) {
if (response.authResponse) {
access_token = response.authResponse.accessToken; //get access token
user_id = response.authResponse.userID; //get FB UID
FB.api('/me', function (response) {
user_email = response.email; //get user email
});
} else {
//user hit cancel button
console.log('User cancelled login or did not fully authorize.');
}
}, {
scope: 'email'
});
}
I'm having some issues integrating Braintree, as well as understanding the concept of how the transaction takes place.
Here's how i currently understand Braintree:
Server Generates ClientToken -> Integrates into html/js -> User receives payment form and sends data to Braintree -> Nonce is sent to Server -> Server sends Transaction to Braintree
Is this correct?
I'm currently on step 1, trying to generate a client token, and i'm getting a NullReferenceException:
public ActionResult Payment(EditContainerViewModel newEdit)
{
//generate client token
newEdit.PaymentInfo.ClientToken = PaymentConstants.Gateway.ClientToken.generate();
return View(newEdit);
}
And heres the Gateway declaration:
public static class PaymentConstants
{
public static BraintreeGateway Gateway = new BraintreeGateway
{
Environment = Braintree.Environment.SANDBOX,
MerchantId = "id",
PublicKey = "publickey",
PrivateKey = "privatekey"
};
}
Heres my view:
#model Sandbox.Models.EditContainerViewModel
<h2>Payment</h2>
<form id="checkout" method="post" action="/checkout">
<div id="payment-form"></div>
<input type="submit" value="Pay $10">
</form>
<script src="https://js.braintreegateway.com/v2/braintree.js"></script>
<script>
// We generated a client token for you so you can test out this code
// immediately. In a production-ready integration, you will need to
// generate a client token on your server (see section below).
var clientToken = "#Html.Raw(Model.PaymentInfo.ClientToken)";
braintree.setup(clientToken, "dropin", {
container: "payment-form"
});
</script>
I'd really appreciate any insight on this topic, especially as i found that the provided ASP.NET examples didn't show the token generation stage.
Thank you!
As said in the comment, i was far too focused on Braintree that i made an extremely beginner error. This serves as a great reminder that you can find the answer by just taking a step back and looking at the error from a new perspective. :)