Passing BraintreeJS paymentnonce payload to ASP.NET Web Form - javascript

I'm trying to integrate Chargebee with Braintree using ChargeBee's API+BraintreeJS (easiest to get PCI compliance). Here is the link of methods that could be used (https://www.chargebee.com/docs/braintree.html). Based on that document, I can conclude that these are the steps
1) Generate clientToken using Braintree SDK for .NET
2) Use BraintreeJS to tokenize all hosted fields and send to Braintree API to get payment nonce
3) Use ChargeBee SDK for .NET and send payment nonce to create subscription in ChargeBee
I've managed to do (1) and (2) but my issue is how could I read the payment nonce during postback? I've tried using controller but still getting null value
Here's my code
<script>
var form = document.querySelector('#cardForm');
var authorization = '<%=clientToken%>';
braintree.client.create({
authorization: authorization
}, function (err, clientInstance) {
if (err) {
console.error(err);
return;
}
createHostedFields(clientInstance);
});
function createHostedFields(clientInstance) {
braintree.hostedFields.create({
client: clientInstance,
styles: {
'input': {
'font-size': '16px',
'font-family': 'courier, monospace',
'font-weight': 'lighter',
'color': '#ccc'
},
':focus': {
'color': 'black'
},
'.valid': {
'color': '#8bdda8'
}
},
fields: {
number: {
selector: '#card-number',
placeholder: '4111 1111 1111 1111'
},
cvv: {
selector: '#cvv',
placeholder: '123'
},
expirationDate: {
selector: '#expiration-date',
placeholder: 'MM/YYYY'
},
postalCode: {
selector: '#postal-code',
placeholder: '11111'
}
}
}, function (hostedFieldsErr, hostedFieldsInstance) {
if (hostedFieldsErr) {
console.error(hostedFieldsErr);
return;
}
submit.removeAttribute('disabled');
form.addEventListener('submit', function (event) {
event.preventDefault();
hostedFieldsInstance.tokenize(function (tokenizeErr, payload) {
if (tokenizeErr) {
console.error(tokenizeErr);
return;
}
// If this was a real integration, this is where you would
// send the nonce to your server.
var noncestr = payload.nonce
alert(noncestr); // Confirm nonce is received.
console.log('Got a nonce: ' + payload.nonce);
$('#paymentmethodnonce').attr("value", noncestr); // Add nonce to form element.
form.submit();
});
}, false);
});
}
</script>
<body>
<div class="demo-frame">
<form action="/" method="post" id="cardForm">
<label class="hosted-fields--label" for="card-number">Card Number</label>
<div id="card-number" class="hosted-field"></div>
<label class="hosted-fields--label" for="expiration-date">Expiration Date</label>
<div id="expiration-date" class="hosted-field"></div>
<label class="hosted-fields--label" for="cvv">CVV</label>
<div id="cvv" class="hosted-field"></div>
<label class="hosted-fields--label" for="postal-code">Postal Code</label>
<div id="postal-code" class="hosted-field"></div>
<div class="button-container">
<input type="submit" class="button button--small button--green" value="Purchase" id="submit" />
</div>
<asp:Label runat="server" ID="lblResult"></asp:Label>
</form>
</div>
<script src="https://js.braintreegateway.com/web/3.8.0/js/client.js"></script>
<script src="https://js.braintreegateway.com/web/3.8.0/js/hosted-fields.js"></script>
</body>
</html>
public partial class Default : System.Web.UI.Page
{
protected string clientToken;
private BraintreeGateway gateway = new BraintreeGateway
{
Environment = Braintree.Environment.SANDBOX,
MerchantId = "xxx",
PublicKey = "xxx",
PrivateKey = "xxx"
};
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//generate clienttoken from braintree sdk
clientToken = gateway.ClientToken.generate();
}
else
{
var paymentnonce = Request.Form["paymentmethodnonce"];
}
}
}

Full disclosure: I work at Braintree. If you have any further questions, feel free to contact support.
The callback that you pass to hostedFieldsInstance.tokenize uses a css selector to find an element with ID paymentmethodnonce and store the generated nonce inside of it. However, there's no element with that ID in the HTML that you submitted. Based on the HTML you've shared, that call should fail, and your subsequent attempt to retrieve paymentmethodnonce using Request.Form will also fail.
You should be able to solve this by adding a hidden input element to your form with the id paymentmethodnonce.
<input type="hidden" id="paymentmethodnonce" />
This will give your tokenize callback a place to put the nonce, and it will make the nonce part of the form, which should allow your Request.Form to retrieve it successfully.

Related

How to make a post request to a protected Laravel API route with JavaScript using the API token?

Description
I have a table, where i collect values from checkboxes with JavaScript. This values should be send to a protected API route in a Laravel backend.
I use the standard Laravel auth setup (out of the box).
Question
What do I have to send with the JavaScript post request for authentication and how do i do that? Can i add a auth token or something like that to the headers?
At the moment i get the reponse:
"This action is unauthorized".
exception: "Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException"
Edit
At the current point of my research the api token seems to be a simple solution for my case. But i can't figure out how to attach the api token to the JavaScript post request.
Thats the JavaScript function for collecting the values storing them in objects.
import SaveData from "../api/SaveData";
export default async function SaveMultipleReports() {
const table = document.getElementById("reports-dashboard");
const rows = table.querySelectorAll("div[class=report-tr]");
let reports = [];
for (const row of rows) {
const checkbox_visible = row.querySelector("input[name=visible]")
.checked;
const checkbox_slider = document.querySelector(
"input[name=show_in_slider]"
).checked;
const report = {
id: row.id,
visible: checkbox_visible,
show_in_slider: checkbox_slider
};
reports.push(report);
}
console.log(reports);
const response = await SaveData("/api/reports/update", reports);
console.log(response);
}
And that is the SavaData function:
export default async function SaveData(api, data) {
const token = document
.querySelector('meta[name="csrf-token"]')
.getAttribute("content");
const url = window.location.origin + api;
const response = await fetch(url, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRF-TOKEN": token,
Accept: "application/json"
},
body: JSON.stringify(data)
});
const result = await response.json();
return result;
}
And thats the line in the api.php:
Route::middleware("can:administration")->post("reports/update", "ReportsController#UpdateAll");
The whole repo is here.
Thanks for your time in advance :)
Edit 2
For now i managed it without JavaScript. Put all the values, i want to update in form and load a hidden input for the ID of every object (the ID is needed for the controller afterwards).
Thanks to this post.
{!! Form::open(["route" => ["admin.reports.multiupdate"], "method" => "PUT", "class" => "report-table"]) !!}
... // some HTML
#foreach ($reports as $report)
<div class="report-tr">
<input type="hidden" name="reports[{{$loop->index}}][id]" value="{{$report->id}}">
<div class="td-name">
<p class="td-text">{{$report->name}}</p>
</div>
<div class="td-flex">{{$report->body}}</div>
<div class="tr-wrapper">
<div class="checkbox-visible">
<div class="checkbox-container">
<input class="checkbox" type="checkbox" name="reports[{{$loop->index}}][visible]" value="1" checked>
<span class="checkmark"></span>
</div>
<label class="table-label" for="visible">Sichtbar</label>
</div>
<div class="checkbox-slider">
<div class="checkbox-container">
<input class="checkbox" type="checkbox" name="reports[{{$loop->index}}][show_in_slider]" value="1"
{{($report->show_in_slider == 1 ? "checked" : "")}}>
<span class="checkmark"></span>
</div>
<label class="table-label" for="show_in_slider">Im Slider</label>
</div>
<div class="td-buttons">
...
#endforeach
<button class="floating-save">
#svg("saveAll", "saveAll")
</button>
{!! Form::close() !!}
And a snippet from the Controller:
public function MultipleUpate(ReportUpdate $request)
{
$reports = $request->input("reports");
foreach ($reports as $row) {
$report = Report::find($row["id"]);
// giving the checkbox 0, if it isn't checked
$isVisible = isset($row["visible"]) ? 1 : 0;
$inSlider = isset($row["show_in_slider"]) ? 1 : 0;
$report->visible = $isVisible;
$report->show_in_slider = $inSlider;
$report->new = false;
if ($report->save()) {
$saved = true;
}
}
if ($saved == true) {
$request->session()->flash("success", "Ă„nderungen gespeichert!");
} else {
$request->session()->flash("error", "Das hat nicht geklappt!");
}
return back();
The ReportUdpate function contains only that:
public function authorize()
{
return true;
}
public function rules()
{
return [
"visible" => "nullable",
"show_in_slider" => "nullable"
];
}
You are talking about authentication but using an authorization middleware. There is a difference between the two.
Read about it here: https://medium.com/datadriveninvestor/authentication-vs-authorization-716fea914d55
With that being said, what you are looking for is an authentication middleware that protects your routes from unauthenticated users. Laravel provides a middleware called Authenticate out of the box for this specific purpose.
Change your route to be like so:
Route::middleware("auth")->post("reports/update", "ReportsController#UpdateAll");

Square Payment Gateway integration in PHP website doesn't redirect to payment portal

I m trying Square payment gateway using the API code found in the below URL
[http://significanttechno.com/square-payment-gateway-integration-using-php]
However, although i have replicated and tried to test the same code in my server, nothing seems to work.
The form doesn't allow me to input card details, and even if i add input tags to it and try to submit the form it doesn't redirect to action page..
The code goes as:
Index.php
<html>
<head>
<title>Square Payment Gateway</title>
<meta charset="utf-8">
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"><![endif]-->
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- link to the SqPaymentForm library -->
<script type="text/javascript" src="https://js.squareup.com/v2/paymentform">
</script>
<!-- link to the local SqPaymentForm initialization -->
<script type="text/javascript" src="sqpaymentform.js">
</script>
<!-- link to the custom styles for SqPaymentForm -->
<link rel="stylesheet" type="text/css" href="sqpaymentform-basic.css">
<script>
document.addEventListener("DOMContentLoaded", function(event) {
if (SqPaymentForm.isSupportedBrowser()) {
paymentForm.build();
paymentForm.recalculateSize();
}
});
</script>
</head>
<body>
<div id="form-container">
<div id="sq-ccbox">
<!--
Be sure to replace the action attribute of the form with the path of
the Transaction API charge endpoint URL you want to POST the nonce to
(for example, "/process-card")
-->
<form id="nonce-form" novalidate action="payment-process.php" method="post">
<fieldset>
<span class="label">Card Number</span>
<div id="sq-card-number"></div>
<div class="third">
<span class="label">Expiration</span>
<div id="sq-expiration-date"></div>
</div>
<div class="third">
<span class="label">CVV</span>
<div id="sq-cvv"></div>
</div>
<div class="third">
<span class="label">Postal</span>
<div id="sq-postal-code"></div>
</div>
</fieldset>
<button id="sq-creditcard" class="button-credit-card" onclick="requestCardNonce(event)">Pay $1.00</button>
<div id="error"></div>
<!--
After a nonce is generated it will be assigned to this hidden input field.
-->
<input type="hidden" id="amount" name="amount" value="100">
<input type="hidden" id="card-nonce" name="nonce">
</form>
</div> <!-- end #sq-ccbox -->
</div> <!-- end #form-container -->
</body>
</html>
sqpaymentform.js
// Set the application ID
var applicationId = "APPLICATION-ID";
// Set the location ID
var locationId = "LOCATION-ID";
function buildForm(form) {
if (SqPaymentForm.isSupportedBrowser()) {
form.build();
form.recalculateSize();
}
}
function buildForm1() {
if (SqPaymentForm.isSupportedBrowser()) {
var paymentDiv = document.getElementById("form-container");
if (paymentDiv.style.display === "none") {
paymentDiv.style.display = "block";
}
paymentform.build();
paymentform.recalculateSize();
} else {
// Show a "Browser is not supported" message to your buyer
}
}
/*
* function: requestCardNonce
*
* requestCardNonce is triggered when the "Pay with credit card" button is
* clicked
*
* Modifying this function is not required, but can be customized if you
* wish to take additional action when the form button is clicked.
*/
function requestCardNonce(event) {
// Don't submit the form until SqPaymentForm returns with a nonce
event.preventDefault();
// Request a nonce from the SqPaymentForm object
paymentForm.requestCardNonce();
}
// Create and initialize a payment form object
var paymentForm = new SqPaymentForm({
// Initialize the payment form elements
applicationId: applicationId,
locationId: locationId,
inputClass: 'sq-input',
autoBuild: false,
// Customize the CSS for SqPaymentForm iframe elements
inputStyles: [{
fontSize: '16px',
fontFamily: 'Helvetica Neue',
padding: '16px',
color: '#373F4A',
backgroundColor: 'transparent',
lineHeight: '24px',
placeholderColor: '#CCC',
_webkitFontSmoothing: 'antialiased',
_mozOsxFontSmoothing: 'grayscale'
}],
// Initialize Apple Pay placeholder ID
applePay: false,
// Initialize Masterpass placeholder ID
masterpass: false,
// Initialize the credit card placeholders
cardNumber: {
elementId: 'sq-card-number',
placeholder: 'XXXX XXXX XXXX XXXX'
},
cvv: {
elementId: 'sq-cvv',
placeholder: 'CVV'
},
expirationDate: {
elementId: 'sq-expiration-date',
placeholder: 'MM/YY'
},
postalCode: {
elementId: 'sq-postal-code',
placeholder: '12345'
},
// SqPaymentForm callback functions
callbacks: {
/*
* callback function: createPaymentRequest
* Triggered when: a digital wallet payment button is clicked.
* Replace the JSON object declaration with a function that creates
* a JSON object with Digital Wallet payment details
*/
createPaymentRequest: function () {
return {
requestShippingAddress: false,
requestBillingInfo: true,
currencyCode: "USD",
countryCode: "US",
total: {
label: "MERCHANT NAME",
amount: "100",
pending: false
},
lineItems: [
{
label: "Subtotal",
amount: "100",
pending: false
}
]
}
},
/*
* callback function: cardNonceResponseReceived
* Triggered when: SqPaymentForm completes a card nonce request
*/
cardNonceResponseReceived: function (errors, nonce, cardData) {
if (errors) {
// Log errors from nonce generation to the Javascript console
console.log("Encountered errors:");
errors.forEach(function (error) {
console.log(' er= ' + error.message);
alert(error.message);
});
return;
}
// Assign the nonce value to the hidden form field
document.getElementById('card-nonce').value = nonce;
// POST the nonce form to the payment processing page
document.getElementById('nonce-form').submit();
},
/*
* callback function: unsupportedBrowserDetected
* Triggered when: the page loads and an unsupported browser is detected
*/
unsupportedBrowserDetected: function () {
/* PROVIDE FEEDBACK TO SITE VISITORS */
},
/*
* callback function: inputEventReceived
* Triggered when: visitors interact with SqPaymentForm iframe elements.
*/
inputEventReceived: function (inputEvent) {
switch (inputEvent.eventType) {
case 'focusClassAdded':
/* HANDLE AS DESIRED */
break;
case 'focusClassRemoved':
/* HANDLE AS DESIRED */
break;
case 'errorClassAdded':
document.getElementById("error").innerHTML = "Please fix card information errors before continuing.";
break;
case 'errorClassRemoved':
/* HANDLE AS DESIRED */
document.getElementById("error").style.display = "none";
break;
case 'cardBrandChanged':
/* HANDLE AS DESIRED */
break;
case 'postalCodeChanged':
/* HANDLE AS DESIRED */
break;
}
},
/*
* callback function: paymentFormLoaded
* Triggered when: SqPaymentForm is fully loaded
*/
paymentFormLoaded: function () {
/* HANDLE AS DESIRED */
console.log("The form loaded!");
}
}
});
payment-process.php
<?php
require 'vendor/autoload.php';
$access_token = 'ACCESS-TOKEN';
# setup authorization
\SquareConnect\Configuration::getDefaultConfiguration()->setAccessToken($access_token);
# create an instance of the Transaction API class
$transactions_api = new \SquareConnect\Api\TransactionsApi();
$location_id = 'LOCATION-ID';
$nonce = $_POST['nonce'];
$request_body = array (
"card_nonce" => $nonce,
# Monetary amounts are specified in the smallest unit of the applicable currency.
# This amount is in cents. It's also hard-coded for $1.00, which isn't very useful.
"amount_money" => array (
"amount" => (int) $_POST['amount'],
"currency" => "USD"
),
# Every payment you process with the SDK must have a unique idempotency key.
# If you're unsure whether a particular payment succeeded, you can reattempt
# it with the same idempotency key without worrying about double charging
# the buyer.
"idempotency_key" => uniqid()
);
try {
$result = $transactions_api->charge($location_id, $request_body);
// print_r($result);
// echo '';
if($result['transaction']['id']){
echo 'Payment success!';
echo "Transation ID: ".$result['transaction']['id']."";
}
} catch (\SquareConnect\ApiException $e) {
echo "Exception when calling TransactionApi->charge:";
var_dump($e->getResponseBody());
}
?>
Please note that i have download the "Square SDK" as mentioned and added location ID and Access token from Square account.
Any help is greatly appreciated..
My Apologies to Every One who banged their heads at this issue and wasted their valuable time on this.,
Turns out the reason for this silly issue is not having the site secured (i.e., Absence of SSL certification)
I came to know about this after going through square-up documentation..
Anyway, Thanks to all.

Set Form authentication in WEB API

Actually i have two project. One for Mvc and another one is Web Api. I have written form as below in mvc project.
<form>
<div class="form-group">
<input type="email" class="form-control" id="email" placeholder="Username">
</div>
<div class="form-group">
<input type="password" class="form-control" id="pwd" placeholder="Password">
</div>
<div class="checkbox">
<input class="customCheckBox" onclick="setIsRemember()" type="checkbox" name="" value="false"><label for=""><span><span></span></span>Remember me</label>
</div>
<button id="buttonSubmit" class="btn btn-default">LOG IN</button>
</form>
Then i have written script for cross domain as below,
$("#buttonSubmit").click(function (e) {
var user =
{
UserName: $("#email").val(),
Password: $("#pwd").val(),
IsRemember: $(".customCheckBox").val()
}
$.ajax({
type: "POST",
url: "http://localhost:55016/api/ajaxapi/loginmethod",
data: user,
success: function (response) {
if (response.Success == false) {
alert("login fail");
}
if (response.Success == true) {
alert("login true");
}
}
});
});
I have written login credential checking in web Api. After login success i have set form authentication as below in web api source,
public class UserLogOn
{
public interface IFormsAuthentication
{
void SignIn(string userName, bool createPersistentCookie);
void SignOut();
}
public IFormsAuthentication FormsAuth
{
get;
private set;
}
public void FormsChange(IFormsAuthentication formsAuth)
{
this.FormsAuth = formsAuth ?? new FormsAuthenticationService();
}
public void LogOnUserCookieCreation(UserValuesForLogOn user)
{
this.FormsChange(null);
this.FormsAuth.SignIn(user.UserName, user.IsRemember);
if (user.IsRemember)
{
HttpCookie cookie = new HttpCookie("SignedIn");
cookie.Values.Add("UserName", user.UserName);
cookie.Values.Add("Password", user.Password);
FormsAuthentication.SetAuthCookie(user.UserName, true);
System.Web.HttpContext.Current.Response.Cookies.Add(cookie);
}
}
public class FormsAuthenticationService : IFormsAuthentication
{
public void SignIn(string userName, bool createPersistentCookie)
{
FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
}
public void SignOut()
{
FormsAuthentication.SignOut();
}
}
When this above code is working if set authentication in same project. But its not working when set authentication using webapi. Please share your suggestion.
Thanks......

Uploading file and posting text input values in one click?

I'm trying build an Asp.net web api for posting files. I found the following example in
https://code.msdn.microsoft.com/AngularJS-with-Web-API-22f62a6e
The Web API method is:
[RoutePrefix("api/photo")]
public class PhotoController : ApiController
{
private IPhotoManager photoManager;
public PhotoController()
: this(new LocalPhotoManager(HttpRuntime.AppDomainAppPath + #"\Album"))
{
}
public PhotoController(IPhotoManager photoManager)
{
this.photoManager = photoManager;
}
// GET: api/Photo
public async Task<IHttpActionResult> Get()
{
var results = await photoManager.Get();
return Ok(new { photos = results });
}
// POST: api/Photo
public async Task<IHttpActionResult> Post()
{
// Check if the request contains multipart/form-data.
if(!Request.Content.IsMimeMultipartContent("form-data"))
{
return BadRequest("Unsupported media type");
}
try
{
var photos = await photoManager.Add(Request);
return Ok(new { Message = "Photos uploaded ok", Photos = photos });
}
catch (Exception ex)
{
return BadRequest(ex.GetBaseException().Message);
}
}
And the file uploader html code: (I added a text input <input type="text" id="test" value="testit" /> for test.
<form name="newPhotosForm" role="form" enctype="multipart/form-data" ng-disabled="appStatus.busy || photoManagerStatus.uploading">
<div class="form-group" ng-hide="hasFiles">
<label for="newPhotos">select and upload new photos</label>
<input type="file" id="newPhotos" class="uploadFile" accept="image/*" eg-files="photos" has-files="hasFiles" multiple>
<input type="text" id="test" value="testit" /> <!--- Added a text input for test -->
</div>
<div class="form-group" ng-show="hasFiles && !photoManagerStatus.uploading">
<ul class="list-inline">
<li><strong>files:</strong></li>
<li ng-repeat="photo in photos"> {{photo.name}}</li>
</ul>
<input class="btn btn-primary" type="button" eg-upload="upload(photos)" value="upload">
<input class="btn btn-warning" type="reset" value="cancel" />
</div>
<div class="form-group" ng-show="photoManagerStatus.uploading">
<p class="help-block">uploading</p>
</div>
</form>
The JS upload function:
function upload(photos)
{
service.status.uploading = true;
appInfo.setInfo({ busy: true, message: "uploading photos" });
var formData = new FormData();
angular.forEach(photos, function (photo) {
formData.append(photo.name, photo);
});
return photoManagerClient.save(formData)
.$promise
.then(function (result) {
if (result && result.photos) {
result.photos.forEach(function (photo) {
if (!photoExists(photo.name)) {
service.photos.push(photo);
}
});
}
appInfo.setInfo({message: "photos uploaded successfully"});
return result.$promise;
},
function (result) {
appInfo.setInfo({message: "something went wrong: " + result.data.message});
return $q.reject(result);
})
['finally'](
function () {
appInfo.setInfo({ busy: false });
service.status.uploading = false;
});
}
However, it seems the value of the added input test cannot be passed to the Web API code?
You need to add custom DTO/POCO class, set the values and then pass it as parameter to your post method. Since file is not a simple type default MediaTypeFormatter of webAPI won't work so you need to build your custom MediaTypeFormatter.
Sample POCO class
Public Class Attachment
{
public string Input {get;set;}
public byte[] Content{get;set;}
}
Custom Media formatter as below
public class CustomFormatter : MediaTypeFormatter
{
/// <summary>
///
/// </summary>
public CustomFormatter()
{
SupportedMediaTypes.Add(new MediaTypeHeaderValue("multipart/form-data"));
}
public override bool CanReadType(Type type)
{
return type == typeof(Attachment);
}
public override bool CanWriteType(Type type)
{
return false;
}
public async override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
{
var provider = await content.ReadAsMultipartAsync();
var modelContent = provider.Contents
.FirstOrDefault(c => c.Headers.ContentType.MediaType == "application/json");
var attachment = await modelContent.ReadAsAsync<Attachment>();
var fileContents = provider.Contents
.Where(c => c.Headers.ContentType.MediaType == "image/jpeg").FirstOrDefault(); // or whatever is the type of file to upload
attachment.Content = await fileContents.ReadAsByteArrayAsync();
return attachment;
}
}
Register the custom media formatter:
private void ConfigureWebApi(HttpConfiguration config)
{
//other code here
config.Formatters.Add(new CustomFormatter());
}
Pass the POCO to your Web-API Controller
public async Task<IHttpActionResult> Post(Attachment attachment)
{
I haven't tested this in Visual Studio, but this is the approach you need to follow
More information here:
http://www.asp.net/web-api/overview/formats-and-model-binding/media-formatters
And a sample here
http://blog.marcinbudny.com/2014/02/sending-binary-data-along-with-rest-api.html#.V5MDDzV7qYg

How to use POST in ApiController

I have searched for at least an hour and a half now and I'm not any closer to learning how to use POST methods in my ApiController. I need an effective way of using post to create a login system that will search my database based on the username/password combination and create a JSON object that I can send back to my web page. Any resources on using post? I've tried to acomplish this with get but I can use any variables more than 'ID'
public IHttpActionResult GetLogin(string id)
{
//Query Database for Unique username.
if (id == "mager1794")
{
//Create Login class with username, and password details.
return Ok( new Models.Login() { id = 1, userName = "mager1794", passWord = "*******" });
}
return Ok(-1);
}
This is what I have for my Get method but I'm just not having any luck creating a POST version of this.
Maybe something like this:
[RoutePrefix("api/account")]
public class AccountController : ApiController
{
public class LoginInfo
{
[Required]
public string Username { get; set; }
[Required]
public string Password { get; set; }
}
[Route("login")]
[HttpPost]
public IHttpActionResult AuthenticateUser(LoginInfo loginInfo)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (!Membership.ValidateUser(loginInfo.Username, loginInfo.Password))
{
ModelState.AddModelError("", "Incorrect username or password");
return BadRequest(ModelState);
}
FormsAuthentication.SetAuthCookie(loginInfo.Username, true);
return Ok();
}
}
Client side:
<form action="#" id="login-form">
<label for="username">Username:</label>
<input type="text" name="username" id="username"/>
<label for="password">Password:</label>
<input type="password" name="password" id="password"/>
<div><input type="submit"/></div>
</form>
<script>
$(document).ready(function () {
$("#login-form").submit(function (e) {
e.preventDefault();
var username = $('#username').val();
var password = $('#password').val();
$.ajax({
type: 'POST',
url: '/api/account/Login/',
data: { Username: username, Password: password },
success: function () {
// refresh the page if username and password are correct
location.reload();
}
});
});
});
</script>

Categories