I am working for the first time with API-s. My first task at my job is to call an API, I am working with the Sandbox version of the API
I am trying to call the Sandbox this way and I should get a static response, but I am getting
"Error at message validation"
what means this and what exactly is a Sandbox and what is a static response?
procedure consentrequest(out transactionid1:transactionIdType);
var
Httprio2 : THTTPRio;
initiateConsentRequest1 : initiateConsentRequest;
initiateconsentrequestresponse1 : initiateconsentrequestresponse;
type2 :consenttype;
consent_init : consent2;
//AccountInfo_PT2 : AccountInfo_PT;
//transactionId1 : transactionIdType;
begin
initiateConsentRequest1 :=initiateConsentRequest.Create;
initiateconsentrequestresponse1 :=initiateconsentrequestresponse.Create;
consent_init :=consent2.Create;
HTTPRio2 :=THTTPRIO.Create(nil);
HTTPRio2.Url := 'https://sandbox.budapestbank.hu/OpenapiSandbox/v1.0.0';
consent_init.type_ :=type2;
consent_init.target := 'HU12345678901234567890123456';
consent_init.validityPeriod :=30;
initiateConsentRequest1.consent :=consent_init;
ShowMessage('Before PT');
initiateconsentrequestresponse1 :=(HTTPRio2 as AccountInfo_PT).initiateConsentRequest(initiateConsentRequest1);
ShowMessage('After PT');
transactionid1 := initiateconsentrequestresponse1.transactionId;
end;
A Sandbox is usually a non-production copy of the API, you might use different creds and get sample data responses. It's a safe practice space for developers.
The error about "message validation" makes me think that the API request you sent was somehow invalid, perhaps it is missing a parameter. Check the docs of the API you are calling and make sure you have the correct verb/endpoint and parameters. Also see if there is more information in the response itself.
I am trying to use the Delphi TREST components to connect to the HRMC VAT API.
I have got as far as obtaining access and refresh tokens, but I cannot get any further.
At the moment, I am trying to retrieve my obligations as follows:-
RESTClient := TRestClient.Create('https://test-api.service.hmrc.gov.uk/organisations/vat/666596898/obligations');
try
RESTRequest := TRESTRequest.Create(RESTClient);
RESTResponse := TRESTResponse.Create(RESTClient);
OAuth2 := TOAuth2Authenticator.Create(RESTClient);
with OAuth2 do
begin
AccessToken := <my access token>;
ResponseType := TOAuth2ResponseType(rtCODE);
TokenType := TOAuth2TokenType(ttBEARER);
end;
with RESTClient do
begin
Authenticator := OAuth2;
ContentType := 'application/json';
end;
with RESTRequest do
begin
Client := RESTClient;
Response := RESTResponse;
Accept := 'application/vnd.hmrc.1.0+json';
Params.AddItem('from', '2017-01-25', pkGETorPOST);
Params.AddItem('to', '2017-01-25', pkGETorPOST);
Execute;
end;
finally
RESTClient.DisposeOf;
end;
This particular code returns the error INVALID_DATE_RANGE. But depending on what dates I use, I also sometimes get CLIENT_OR_AGENT_NOT_AUTHORISED.
Can anyone shed any light on where I am going wrong?
Perhaps it doesn't like the start and end dates being the same? It does say invalid date RANGE rather than invalid dates.
I worked it out finally. It was a problem with my Test User credentials. I generated them from the HMRC website, but I discovered from other posts that there is a problem generating them that way. When I created a user via the API, it works fine!
I hope this helps someone.
I want to request some api and set the response as a nginx variable. But it says "set_by_lua_block" directive is not allowed here. How can I achieve this?
http {
set_by_lua_block $hostIp {
local http = require 'resty.http'
local httpc = http.new()
local res, err = httpc:request_uri('http://some-pai')
local body, err = res:read_body()
ngx.log(ngx.INFO, "Using ngx.INFO")
ngx.log(ngx.INFO, body)
return body
}
...
}
set_by_lua_block is not allowed in http context
https://github.com/openresty/lua-nginx-module#set_by_lua
set_by_lua_* may be used within server context.
But your code will not work anyway because resty.http uses cosocket API.
At least the following API functions are currently disabled within the
context of set_by_lua:
Output API functions (e.g., ngx.say and ngx.send_headers)
Control API functions (e.g., ngx.exit)
Subrequest API functions (e.g., ngx.location.capture and ngx.location.capture_multi)
Cosocket API functions (e.g., ngx.socket.tcp and ngx.req.socket).
Sleeping API function ngx.sleep.
If you really need to request something once before nginx start - write script and set environment variable. Then
set_by_lua $my_var 'return os.getenv("MY_VAR")';
I realise that there's a duplicate question, but it wasn't answered, so I'm raising the question again with my own code that doesn't work.
I'm trying to send HTTP requests to the Google Calendar/v3 API using the REST client library components in DELPHI XE5 Update 2 (TRESTClient, TRESTRequest, TRESToAuth2Autenticator, TRESTResponse).
Why doesn't the following work? All I get is a Bad Request stating "This API does not support parsing form-encoded input". I have specified application/json in the Client and the Request, yet it is ignoring this and still sending as Form Encoded.
JB := TlkJSONObject.Create;
JBStart := TlkJSONObject.Create;
JBEnd := TlkJSONObject.Create;
try
JB.Add('Summary', 'Another Test');
JBStart.Add('DateTime', '2016-02-09T17:00:00');
JBStart.Add('TimeZone', 'Europe/London');
JB.Add('Start', JBStart);
JBEnd.Add('DateTime', '2016-02-09T18:00:00');
JBEnd.Add('TimeZone', 'Europe/London');
JB.Add('End', JBEnd);
Event := TlkJSON.GenerateText(JB);
finally
FreeAndNil(JB);
end;
Client.BaseURL := 'https://www.googleapis.com/calendar/v3/calendars/' + CalID + '/events?key=' + ClientInfo.APIKey;
Client.ContentType := 'application/json;';
Req.AddBody(Event, ctAPPLICATION_JSON);
Req.Method := rmPOST;
Req.Execute;
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 2 years ago.
Improve this question
For those building RESTful APIs and JS front-end apps in Go, how are you managing authentication? Are you using any particular libraries or techniques?
I'm surprised to find so little discussion about this. I keep in mind answers like the following, and am trying to avoid developing my own implementation:
Authentication Form in ASP.Net
Is everybody coding their own solution, separately?
This question gets a ton of views--and has a Popular Question badge--so I know there is a lot of latent interest in this topic, and many people are asking exactly the same thing and not finding answers on the Interwebs.
Most of the available information results in the textual equivalent of the hand wavy thing, left as an "exercise for the reader." ;)
However I've finally located one concrete example, (generously) provided by a member of the golang-nuts mailing list:
https://groups.google.com/forum/#!msg/golang-nuts/GE7a_5C5kbA/fdSnH41pOPYJ
This provides a suggested schema and server-side implementation as a basis for custom authentication. The client-side code is still up to you.
(I hope the author of the post sees this: Thanks!)
Excerpted (and reformatted):
"I would suggest something like the following design:
create table User (
ID int primary key identity(1,1),
Username text,
FullName text,
PasswordHash text,
PasswordSalt text,
IsDisabled bool
)
create table UserSession (
SessionKey text primary key,
UserID int not null, -- Could have a hard "references User"
LoginTime <time type> not null,
LastSeenTime <time type> not null
)
When a user logs in to your site via a POST under TLS, determine if the password is valid.
Then issue a random session key, say 50 or more crypto rand characters and stuff in a secure Cookie.
Add that session key to the UserSession table.
Then when you see that user again, first hit the UserSession table to see if the SessionKey is in there with a valid LoginTime and LastSeenTime and User is not deleted. You could design it so a timer automatically clears out old rows in UserSession."
Another possible solution is Authboss, recently announced on the mailing list.
(I haven't tried using this library.)
Also see Best way to make a webapp with user auth?
You would use middleware to do the authentication.
You can try go-http-auth for basic and digest authentication and gomniauth for OAuth2.
But how to authenticate really depends on your app.
Authentication introduces state/context into your http.Handlers and there have been some discussion about that lately.
Well known solutions to the context problem are gorilla/context and google context described here.
I made a more general solution without the need of global state in go-on/wrap that may be used together or without the other two and nicely integrates with context free middleware.
wraphttpauth provides integration of go-http-auth with go-on/wrap.
Answering this in 2018. I suggest using JWT(JSON Web Token). The answer you marked solved has drawback, which is the trip it did front(user) and back(server/db). What is worse if user did frequent request that need auth, will result in bloated request from/to server and database. To solve this use JWT which store the token in user end which can be used by user anytime it needs access/request. No need trip to database and server processing to check the token validity take short time.
Honestly, there's a lot of authentication methods and techniques that you can mount into your application and that depends on applications business logic and requirements.
For example Oauth2, LDAP, local authentication, etc.
My answer assumes you are looking for local authentication which means you manage the user's identities in your application.
The server must expose a set of external API allow users and admins
Managing the accounts and how they want to identify themselves to Server to achieve trustable communication.
you will end up creating a DB table holding the user's information.
where the password is hashed for security purposes See How to store the password in the database
let assume app requirements to authenticate users based on one of the following methods:
basic authentication (username, password):
This auth method depends on user credentials sets in Authorization header encoded in base64 and defined inrfc7617, basically when the app receives the user requests its decodes the authorization and re-hash the password to compare it within DB hash if it's matched the user authenticated otherwise return 401 status code to the user.
certificate-based authentication:
This auth method depends on a Digital Certificate to identify a user,
and it's known as x509 auth, so when the app receives the user requests it reads the client's certificate and verifies it that matches the CA Root certificate that is provided to the APP.
bearer token:
This auth method depends on short-lived Access tokens, The bearer token is a cryptic string, usually generated by the server in response to a login request. so when the app receives the user requests it reads the authorization and validates the token to authenticate the user.
However, I'd recommend go-guardian
for authentication library which it does through an extensible set of authentication methods known as strategies. basically Go-Guardian does not mount routes or assume any particular database schema, which maximizes flexibility and allows decisions to be made by the developer.
Setting up a go-guardian authenticator is straightforward.
Here the full example of the above methods.
package main
import (
"context"
"crypto/x509"
"encoding/pem"
"fmt"
"io/ioutil"
"log"
"net/http"
"sync"
"github.com/golang/groupcache/lru"
"github.com/gorilla/mux"
"github.com/shaj13/go-guardian/auth"
"github.com/shaj13/go-guardian/auth/strategies/basic"
"github.com/shaj13/go-guardian/auth/strategies/bearer"
gx509 "github.com/shaj13/go-guardian/auth/strategies/x509"
"github.com/shaj13/go-guardian/store"
)
var authenticator auth.Authenticator
var cache store.Cache
func middleware(next http.Handler) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Println("Executing Auth Middleware")
user, err := authenticator.Authenticate(r)
if err != nil {
code := http.StatusUnauthorized
http.Error(w, http.StatusText(code), code)
return
}
log.Printf("User %s Authenticated\n", user.UserName())
next.ServeHTTP(w, r)
})
}
func Resource(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Resource!!\n"))
}
func Login(w http.ResponseWriter, r *http.Request) {
token := "90d64460d14870c08c81352a05dedd3465940a7"
user := auth.NewDefaultUser("admin", "1", nil, nil)
cache.Store(token, user, r)
body := fmt.Sprintf("token: %s \n", token)
w.Write([]byte(body))
}
func main() {
opts := x509.VerifyOptions{}
opts.KeyUsages = []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}
opts.Roots = x509.NewCertPool()
// Read Root Ca Certificate
opts.Roots.AddCert(readCertificate("<root-ca>"))
cache = &store.LRU{
lru.New(100),
&sync.Mutex{},
}
// create strategies
x509Strategy := gx509.New(opts)
basicStrategy := basic.New(validateUser, cache)
tokenStrategy := bearer.New(bearer.NoOpAuthenticate, cache)
authenticator = auth.New()
authenticator.EnableStrategy(gx509.StrategyKey, x509Strategy)
authenticator.EnableStrategy(basic.StrategyKey, basicStrategy)
authenticator.EnableStrategy(bearer.CachedStrategyKey, tokenStrategy)
r := mux.NewRouter()
r.HandleFunc("/resource", middleware(http.HandlerFunc(Resource)))
r.HandleFunc("/login", middleware(http.HandlerFunc(Login)))
log.Fatal(http.ListenAndServeTLS(":8080", "<server-cert>", "<server-key>", r))
}
func validateUser(ctx context.Context, r *http.Request, userName, password string) (auth.Info, error) {
// here connect to db or any other service to fetch user and validate it.
if userName == "stackoverflow" && password == "stackoverflow" {
return auth.NewDefaultUser("stackoverflow", "10", nil, nil), nil
}
return nil, fmt.Errorf("Invalid credentials")
}
func readCertificate(file string) *x509.Certificate {
data, err := ioutil.ReadFile(file)
if err != nil {
log.Fatalf("error reading %s: %v", file, err)
}
p, _ := pem.Decode(data)
cert, err := x509.ParseCertificate(p.Bytes)
if err != nil {
log.Fatalf("error parseing certificate %s: %v", file, err)
}
return cert
}
Usage:
Obtain token:
curl -k https://127.0.0.1:8080/login -u stackoverflow:stackoverflow
token: 90d64460d14870c08c81352a05dedd3465940a7
Authenticate with a token:
curl -k https://127.0.0.1:8080/resource -H "Authorization: Bearer 90d64460d14870c08c81352a05dedd3465940a7"
Resource!!
Authenticate with a user credential:
curl -k https://127.0.0.1:8080/resource -u stackoverflow:stackoverflow
Resource!!
Authenticate with a user certificate:
curl --cert client.pem --key client-key.pem --cacert ca.pem https://127.0.0.1:8080/resource
Resource!!
You can enable multiple authentication methods at once. You should usually use at least two methods
Another open source package for handling authentication with cookies is httpauth.
(written by me, by the way)
Take a look at Labstack Echo - it wraps authentication for RESTful APIs and frontend applications into middleware that you can use to protect specific API routes.
Setting up basic authentication, for example, is as straightforward as creating a new subrouter for the /admin route:
e.Group("/admin").Use(middleware.BasicAuth(func(username, password string, c echo.Context) (bool, error) {
if username == "joe" && password == "secret" {
return true, nil
}
return false, nil
}))
See all of Labstack's middleware authentication options here.