Transcript
This transcript was autogenerated. To make changes, submit a PR.
Hello everyone, welcome to Conf 42 Golang.
In this talk you will learn how to secure go APIs with
decentralized identity tokens. My name is Mohammad Shahbaz
Alam, a developer advocate at Magic, an authentication
based company which will help you with all your authentication
and authorization needs. So in this talk we will learn
how the user trust model of the Internet is broken,
what is decentralized identity token, and we will
learn auth magic. We will also see what is
authentication authorization and also see how
to build a go API and then later on go on
to secure that go API with magic.
So let's get started. Users think of secrets
or password very specific to them to verify
identity and often hand them off to
apps owned by various companies. 59% of all
users reuse their passwords across apps.
I'm pretty sure someone in the audience have used
same password for multiple application users entrust
companies to store their secrets securely and
responsibly, but many companies roll
their own authentication without the prior knowledge of
security at all. Users access the company's services
by sewing the secret again and again to the developer,
and every time that secret is shown, there is a risk
of exposing it to the hackers. Consider this step as similar
to writing your secret in a piece of paper
and giving it to the application developer.
Companies might get hacked and lose secrets
along with users trust. 48% of customers never
come back after a breach. The equifax breach has
cost them at least $1.4 billion users.
The hackers users stolen secrets to impersonate
users to access their vital online services. They use
the same stolen password at multiple applications because
of password reuse. And this problem compounds now
that there are many companies acting on behalf of users to authenticate for
them and the user's identity is no longer
in their own hands, but controlled by a handful of large corporations.
So what people tried before magic, they came up with zero knowledge
authentication, a key based model.
Instead of users thinking of secret themselves, they will use
the blockchain based public private key pairs which are
randomly generated to access applications.
It has its pros and cons. The pros were users
have complete control of their identity, which is good companies
can't know user secret. Again, more secure and good
users can use the same secret to access application,
which is a cleaner trust model where there are no
identity silos by companies, but it has its
cons. Users are likely to lose their keys.
I'm sure many of you have forget your
password and we do too, which will lock them but of use
good and lose their online identities or worse,
get them stolen. So concept of using a key on the Internet
is too unfamiliar for mainstream users because of
bad UX and how magic improves the trust.
So far magic uses a delegated key management
model which leverages large infrastructure as
a service and secure user keys
with hardware security modules consider hardware security modules
are similar to your UB keys which are a hardware device
used as second factor authentication to store your private
keys. Consider these hardware security modules
on the cloud with technology. Magic leverages
these with technology that hides and protects users private
keys from companies and even from magic.
It brought additional pros which are magic provides
familiar passwordless auth UX like
email, passwordless email, magic link, social logins,
web authent to users for
them to retrieve their keys which is a better UX and they
can no longer lose their keys. Magic doesn't
store passwords and cannot know users'keys or secret
which is a more security and it provides more
trust. Magic has native support for multiple blockchain
and it has only one con which is that it is
reliance on single infrastructure as a service. So the
question is what is did token? Did tokens
created by magic is adapted by prior text like
JWT which is JSON web token and
W three C's did protocol. It is encoded
as a base 64 JSON string tuple representing proof
and claim. It leverages the Ethereum blockchain and elliptic curve
cryptography to generate verifiable proofs of identity
and authorization. These proofs are encoded in a
lightweight digital signature which is shared between client
and server to manage permissions, protect routes
and resources, or authenticate users.
Decentralized identity token looks similar to
this, which it has its proof and claim.
The claims are the data representing the user's access.
It has user's information and the proof is
assigned data with Ethereum's personal sign method and we get
proof but of the claim and then we encode this
proof and claim and by that we get a
did token and generating a did token.
This is how a pseudo code look like. It has
a claim representing the user's data.
The issuer used here is the user's public
address and again that claim is signed
by Ethereum's personal sign method. The claim has
issued at expiration subject not
valid before time and bunch of other information
and this again this encodes the did token.
We encode the did token so it can be transported over HTTP.
The decentralized Id token specification can be found on
docs at magic docs and visit the decentralized
Id section where you will get more understanding of what
each key does. This is how you generate a did
token with magic. This is a JS implementation of it.
You can do it in Android, iOS and react
native applications as well. And this is how you get a did token
at client side. So first we import the
magic SDK and then we instantiate that
magic with API key. And this is an
API key which you get on signing up to a magic account.
We will see later in this talk.
And then once you do with two line of code above.
The third one is to users the auth
module of magic SDK and call a function called login
with magic link and pass on the user's email address.
And once that is done the user will be able to
log in with a magic email a magic
link on their email by default. This function also
gives you a did token. If you store it in a constant called did
tokens, it will give you a by default did token with a
lifespan of 15 minutes. But if you want to extend the lifespan of a
did token, consider the lifespan as a validity of your
token and you can use the users module
of SDK and call the getid token and again
pairs on the lifespan. And this lifespan is in seconds.
If you want more than 15 minutes, pass on more than 902nd.
And to learn more about it you can visit the decentralised magic
doc to see how you can generate a did token with magic.
So understand what is authentication and what
is authorization, and then we will see how we do it,
how we differentiate here at magic and how it works.
So authentication is something are you the
one who you say you are? And if your answer is yes,
this is what authentication does and authorization
is something like are you allowed to do this action?
So if your answer is yes because you are allowed to do it,
these are called authorization. Do you have the
permissions to access that particular resource or route?
And in this talk we will see both of it,
how to authenticate and then authorization. So once
you log into magic dashboard after
signing up, you will see something like this, your first app,
and we use the API key in the client side and
we use the secret key at the server side. We will see
in action how that happens in Go APIs.
So authentication the login with magic
link flow, how magic link get
generated, how the authentication is handled here at
magic. So consider a login request
comes from your browser app which has a magic SDK
loaded the magic iframe loaded
onto your application, iframe is loaded into your application
and a login request is made to magic
service and once that is done there is
a polar going on which checks every
2 seconds whether the login has been done or
not, and that has been passed to magic services. Magic services
send a magic link email to
user's inbox. User opens that email,
click on the confirm link and the login is done.
And at that time the polar gets
resolved and it says that the login has been
done and it resolves the SDK promise. Optionally, you can
have a browser app, a different context, you can redirect
to different URL and
once you have the authentication, for example,
user has the browser using the client application,
theyre log in and they get a did token in return.
In that did tokens there is a bunch of information,
but users we pass that did tokens in the
authorization header when we call the server
at a protected route and when we want to protect
a route, we would encapsulate that
functions that route inside a protected method. We will see
how that looks and then we try to access that API
route by passing the did token in know authorization header
at the server. We extract the did token from the header,
we validate that token using magic SDK and once
that is done the did token is valid token. We say that
like yeah, go on and see. Because you have the permissions,
you have a valid token to access the resources. So let
us see how to build go API and how it
looks. This is a simple go API
main go file which has under normal stuff,
but I have used gorilla mux over here to
handle most of our routing.
What it has we have bunch of imports and then
we have handle request function which handles
most of the things. And then we have home page
which returns a response. Welcome to homepage.
As you can see here and the server is running and then
we have a protected page which says which is
protect. Right now it's not protected but it's accessible
without the token. But the ideal goal is to protect
this particular route with a did token. And then
we have something called myrouter handle
function. And this is how we have main route,
the home route and we call a function over here which
is a home page and then we have a protected route calling
the protect function. So if you try
to run this you will see multiple things. And we
are using port 9000. So this is how you listen and serve.
So this is a very normal go API. The idea
is to just simulate and see how we can protect
a normal API of Go.
So the server is running on localhost
9000 and then when you try to see a protected route,
it says that you are seeing a protected page without the token.
So just so that we don't have to worry
about how things happen here,
I will go ahead and convert this particular
application into a protected application and see how it
looks. So this is what you will see what
I have added multiple things and I'll explain one by
one. So this is the same function,
same API, which has like welcome to home page, but when
you try to access the protected page, it says that the bearer token
is required to access this rot. So this token
is what we will be working on, how to get that token,
how to verify that token and everything around that token.
And here the token is the decentralized identity
token, right? So we are using something
called env to process and load the
environment variable from env and we are using something
called magic secret key. As I said, at the server side you
users the magic secret key and at the client side
you will use the magic API key, right?
So apart from this, the gorilla max
which is same, and I have just added env
to access and load the env variable so that
we can use the magic secret keys,
right? And apart from that I have used a constant
called authparer with bearer. And here we
have imported this magic admin go from
magic Labs. So we'll see how you could do that.
And that's it. So after
getting the magic secret key to a
variable, we instantiate the
magic SDK, calling client new and then passing
on the secret. And this is how we instantiate a magic
SDK. And then what we check is
we check a bearer token. So we first define
a function which will act
as a middleware, right, middleware to
a protected road protected route. So what
it does is that it first checks whether
the did exists in HTTP header or not. This is how
we extract an authorization header and we compare that
it has the prefix of bearer
what we have defined here. And once the bearer token
is present we pass on. If not, we say that bearer token is required
to access this route and we will see everything in action when we'll do the
demo. And then once
we have a bearer token in the authorization header,
we go on to extract that bearer token from the
authorization header and that is what we have,
which is a did token passed on from the client
side. And then we create a token instance to interact
with the did token. And this is how we do it. You can check
more about this in the docs later on. And we check
here is whether the did token is malformed
or not. If there is an error it
will throw out that particular error.
At this stage leveraging is fine and
this is what we do at server side.
Every did token must be validated at server side.
So you know you are working with a valid did token
and this is how you do a
token validate at go server.
And if there is a token failed
validation it will throw that error. And apart from
that you can simply pass on.
You can step ahead with next resolve with
request and response,
right? But this is what you can
get more information about that did token, what it contains.
So magic SDK is how we instantiate here
the magic and then we call the user module
of goads SDK and
we call a function called get metadata by token. Here the
token is did token. We pass on that and we get all those user
info. So user info has email issuer and
public address. We will see in action how it looks and
once that is done the next function will go on
to continue with the response and request.
So this is how we define a checkbearer
token middleware which checks the bearer token as
well as validate the token and extract the user info
from magic function called get metadata
by token, right? And this is what the handle
request is. It's similar to the previous one.
As you can see this is same what we added here
is under the we wrap the protected page function inside check
bearer token middleware. So this is how
you protect your route and nothing
fancy over here. It's as simple as the previous one. And we
have a home page function which just says welcome to homepage
and a protected page which says
you have access to c protected page. But when
you try to see it inside a browser, it says bearer
token is required. And to access this particular
route you would need access to bearer token,
right? Or specifically the did token.
So how do you get a did token and how to use that?
So this is a front end of the
application. You can generate front end from multiple
templates I have used. Next what you would do
is just run NPX and make magic. We will see how
it looks. And this is how you get a did token
similar to this. So what has happened? Similar to what I was
saying, how you do the auth login with
magic link and pass on the email, right? And additionally
you can create a did token calling the user
module and calling the function getid token and passing
on the lifespan here, the lifespan of the did token is
8 hours. Consider this as a second, the second minutes and
hours. So this is equivalent to 8 hours,
right? And so we get a did token, you can see
how it looks. The front end of the code is hosted
on GitHub under a repo called
frontend go API you can check out later on. So this
is how you get a did token and simply you can clone.
There will be steps to get functions, but when you clone
this you just need to replace these
variables, right. The publishable API key and the secret
key. Secret key can also be used at
the client side as well. But here it is used inside
a next application which has something called API
and you pass on and you protect multiple
things. So let's not go into that which is beyond the scope
of this video and talk. So let's grab this
did token and once you do that you will be able to
get a did token by logging into your application,
providing your email address. Email will come to your
email id. You just need to open that, click on
that, you will be able to log in. If not you will see a multiple
demo on Magic YouTube channel.
So grab that, grab that did token which
you get which has a lifespan of 8 hours. Copy this
and try to access the protected route.
Right. This is hosted on local host 9009.
The other one is hosted on 9000 which is not protected.
But let's see because we have added did token and verify
functions in this go APIs. When you try to access
normal one it's same like welcome to homepage. And when
you try to access the protected route again it will
have the same result like bearer token is required to access this route.
So how do you access that? This is what I'm using. This is
a postman. You can use insomnia and any other tool
just to test and see, but usually you will do normal
fetch from the front end of your applications.
Or maybe you will use axios to access these kind of information
and pass as an authorization header from
there. So select
the authorization here and from the drop down
select the bearer token and pass on the did token
which I have grabbed so I'm not going to use the previous one.
Let's paste what I have copied from that application and try to
access it. So when you try to access it it
gives you bunch of information which is email.
And when you decode that did token at the server side
what we are calling is get users metadata
and we are calling that function. We are getting the metadata
which has its email issuer and public address. So it
has these information apart from that because
we have a protected page which has a message that you have
access to c protected page. So let me show how it looks.
This is what I'm referring. So this is the protected page
part. And when you do the check bearer
token and this is where we have
used the user info and email issuer and
public address to return that in the response,
right? So that's really cool. And you
have your application, your API protected by
magic SDK and you are using the
id token to fetch and access those of information.
So what next and how do you get that? So visit
magic link, try for free account by default,
when you try to do it, there will be 10,000 free logins
you will get. If you want more than that, there is a referral program going
on. By doing that you can get more like 10,000
plus 90,000 free logins if you share with your
friends. Once you sign up, you will be able to create an application
similar by going to this or maybe by default you will have
your first application created, right? And then you can create your application
and then you will have this publishable API key.
Feel free to share this publishable API key which is not but
not recommended, but you can share it, but no issue with that.
One thing to note is that whichever combination you are
using, the front end has this API.
It should have the same secret key from the same application.
Otherwise you will get multiple bunch of errors, right?
And you can also enable multiple social logins if you want to have it.
Right now it says just the email link you can create
Google, GitHub, Facebook and so on, even discord.
That's how you get the API key and the secret key and
that's it. Right? So what next apart
from this? I'm saying what next theyre you can do multiple things.
You can build a full fledged rest API
which has its cred application, everything around that.
So theyre is a guide on magic website visit that.
It's called securing a go back scrappy twitter API with magic
and you'll be able to play around and see how it looks even
run in Postman and see how a posting a
tweet look, getting all information about the tweets. Get a single
tweet and a bunch of information. And to get a did token and
play with this particular demo, just visit this link
and you'll be able to again similar application.
You just need to sign in and you will get another did
token like this, right? And I have also
used this. This is what this crappy API looks
like, which has the rest form of it API which
has the crud application this is how you create
an application. And before creating a tweet,
let's see what we have in get all tweets.
If you try to fetch this, you will see one tweet
from Mary Chris, a colleague of mine,
that this is our first default tweet. And if
you want to create a tweet again, this is protected route,
right? And if the body has like this is our second tweet.
If we try to access it, it says that the did token
is malformed because I think there is an authorization header
or something is missing, right. So let's try and add that
better token from the link what I have just
copied. And you would need to sign in and
do the same process. Try to access and have this.
So it says that there is a success. We have, this is a second tweet.
And as you can see, the author is my email Id,
which is what I am logged into, right. I'm logged
in with Shebaz at magic Link and it returns
that thing. And you can also see and validate from fetching
all the tweets. And similarly, if you for example,
try to delete a tweet, for example, if you try to delete the
tweet which is owned by Mary Chris in this case, and if you
try to access this, it will say like something is
malformed because it's missing. So let's try and again copy
and paste the same did tokens try to access it. It says,
oh, you cannot delete someone else's tweet because this
tweet is created by makers and the second one is created
by me. If I try to do this, it will delete my tweet.
So there is multiple things you can see, get a single tweet and
then save user info and multiple things you can learn
about. So this is a good blog post if you want
to build a restful API and secure those API using
magic. So this is again a link which I'll
share in the slides. I have used this particular section.
Get started with magic. And if you want to do this, you alternatively
need to either import similar to this or explicitly
say go get pass on the GitHub magic link,
magiclabs and then magic admin go. And this
is how we created the instance. And we created a token instance.
What we have used is get metadata by
token which returns magic user info which has issuer,
email and public address. Right. You can see
the examples. It has similar examples similar to
what I have used and you can use and learn more about it.
So there are a bunch of resources, how you do that and how you validate,
how to get the issuer public address and so on.
If you want to do the front end side of it, we have used get
metadata because you can use get metadata from the
front end side of it. There are things called login with magic
link which has multiple examples.
It has auth modules, it has user modules to
leaks anything around front end side. You would go to the
magic docs and see the client SDK and if you want to work with
admin SDK you will go to the admin SDK side of
it. For example because we are working with Go, you will do that in go.
So let's come back to the slides and see what we have done
and recap what we did right. So we built in
Go API and then we later on went on to secure that
particular the basic routes and we also saw how a crud
applications looks like how the restful API looks
in Go API where you can learn more. But those things right
to get started locally in seconds with magic you just need to
run NPX make magic and select from that.
Theyre is a bunch of templates to see at least
right now it has more front end application but there is I
think one server side application express
APIs and go API. If you want go API to be
here in NPX makemagic do let us know on our twitter
handle or our community page. So we have used this template.
This is how you define a template and get started very quickly.
NPX make magic and pairs on the template with next but
you feel free to explore other templates as well and share your feedback.
If you have any questions do let me know on twitter handle this is my
handle or tag magic labs and let
us know that as well. So these are the resources
about the talk. Like the front end of the application is hosted
on GitHub under a repo called frontend Go API
or Go server is magic Go API. You can see these
things. I'll share the slide link with you as well
so you can see and learn more about these resources.
And there is magic Go admin SDK. If you want to learn more
about decentralized identity specifically to
magic, the first link would be the best place. But if you want to learn
about what is did and learn more about the did proper
what it is, you will go to w three c this
page and then if you want to know what is a did token and what
it does. And again bunch of things is on our docs visit our
docs if you want to integrate to multiple applications and
maybe use different front end visit our guides and see how
that is happening. We have a community page.
You are always welcome to join us the authentication
community where we share and learn from each other. So join that
community and share your experience and what you are building with
magic. So I think that's it. If you have anything specific
to me, these are the links you can connect with me or
simply as if you have a terminal and if you have node installed
just run npx mdxvz alam my username and
you will see similar options like this and you will be able to follow me
across social media. So again, once again thank you
conf 42 golang for having me.
So if you have any questions related to go APIs, magic authentication,
serverless, passwordless, anything around authentication,
you can reach out to magic labs or me. I would be
happy to help and answer your queries. So once again
thank you for having me and enjoy the rest
of the conference.