Skip to content

Latest commit

 

History

History
184 lines (132 loc) · 5.08 KB

3-hash-passwords.mdx

File metadata and controls

184 lines (132 loc) · 5.08 KB
sidebar_position sidebar_label description keywords seoFrontMatterUpdated
4
Hash Passwords
Learn how to securely hash passwords and handle them within your API.
hasura
hasura ddn
custom business logic
password hashing
guide
false

import GraphiQLIDE from "@site/src/components/GraphiQLIDE"; import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem";

Hash Passwords

Introduction

In this recipe, you'll learn how to securely hash passwords to protect user credentials in your application. Password hashing is an essential part of securing sensitive information before storing it in your database.

:::info Prerequisites

Before continuing, ensure you have:

NB: Bcrypt is a common, well-tested library for password hashing in various languages, and it's widely supported across many systems.

:::

Recipe

Step 1. Write the function

```sh title="In your connector's directory, install the bcrypt package:"
npm install bcryptjs
```

```typescript title="In your functions.ts file, add the following:"
import bcrypt from "bcryptjs";

export async function hashPassword(password: string): Promise<string> {
  const salt = await bcrypt.genSalt(10);
  const hashedPassword = await bcrypt.hash(password, salt);

  // Add your own logic here to hit your Hasura endpoint and perform an insertion

  return hashedPassword;
}
```
```plaintext title="In your requirements.txt, add the bcrypt package:"
bcrypt==4.2.0
```

```python title="In your functions.py file, add the following:"
from hasura_ndc import start
from hasura_ndc.function_connector import FunctionConnector
import bcrypt

connector = FunctionConnector()

@connector.register_mutation
async def hash_password(password: str) -> str:
    salt = bcrypt.gensalt()
    hashedPassword = bcrypt.hashpw(password.encode("utf-8"), salt).decode("utf-8")

    # Add your own logic here to hit your Hasura endpoint and perform an insertion

    return hashedPassword

if __name__ == "__main__":
    start(connector)
```
```sh title="Add the bcrypt package and its dependencies to your connector's go.mod:"
go get golang.org/x/crypto/bcrypt
go get golang.org/x/net/[email protected]
```

```go title="In a Go file inside your functions directory, add the following:"
package functions

import (
  "context"
  "fmt"
  "golang.org/x/crypto/bcrypt"

  "hasura-ndc.dev/ndc-go/types"
)

// HashPasswordArguments defines the input arguments for the function
type HashPasswordArguments struct {
  Password string `json:"password"`
}

// HashPasswordResult defines the output result for the function
type HashPasswordResult string

// ProcedureHashPassword hashes a password string and returns it as a string result
func ProcedureHashPassword(ctx context.Context, state *types.State, arguments *HashPasswordArguments) (*HashPasswordResult, error) {
  hashedPassword, err := bcrypt.GenerateFromPassword([]byte(arguments.Password), bcrypt.DefaultCost)
  if err != nil {
    return nil, fmt.Errorf("failed to hash password: %v", err)
  }

  // Add your own logic here to hit your Hasura endpoint and perform an insertion

  result := HashPasswordResult(string(hashedPassword))
  return &result, nil
}
```

Step 2. Track your function

To add your function, generate the related metadata that will link together any functions in your lambda connector's source files and your API:

ddn connector introspect <connector_name>

Then, you can generate an hml file for the function using the following command:

ddn command add <connector_name> "*"

Step 3. Test your function

Create a new build of your supergraph:

ddn supergraph build local

In your project's explorer, you should see the new function exposed as a type and you should be able to execute a mutation like this:

<GraphiQLIDE query={mutation HashPassword { hashPassword(password: "Thisisthesecure1!") }} response={{ "data": { "hashPassword": "$2a$10$0kqTP3HNd72oz8Q/qEA2PeOf.sr8jth/zMuICGmZu1qMCfA5N/b/a" } }} />

Wrapping up

In this guide, you learned how to enhance your API by securely hashing passwords before storing them in your database. Your API clients can invoke this mutation and you can handle all of the logic of hashing and inserting the new record directly from your API.

Learn more about lambda connectors

Similar recipes