SQL-based authentication: Difference between revisions

Go solution
m (→‎{{header|Tcl}}: Add missing pipe character in template usage)
(Go solution)
Line 196:
 
From the command line, <tt>program add user password</tt> to add users, and <tt>program auth user password</tt> to see if the user with that password is authorized or not.
 
=={{header|Go}}==
<lang go>package main
 
import (
"bytes"
"crypto/md5"
"crypto/rand"
"database/sql"
"fmt"
 
_ "github.com/go-sql-driver/mysql"
)
 
func connectDB() (*sql.DB, error) {
return sql.Open("mysql", "rosetta:code@/rc")
}
 
func createUser(db *sql.DB, user, pwd string) error {
salt := make([]byte, 16)
rand.Reader.Read(salt)
_, err := db.Exec(`insert into users (username, pass_salt, pass_md5)
values (?, ?, ?)`, user, salt, saltHash(salt, pwd))
if err != nil {
return fmt.Errorf("User %s already exits", user)
}
return nil
}
 
func authenticateUser(db *sql.DB, user, pwd string) error {
var salt, hash []byte
row := db.QueryRow(`select pass_salt, pass_md5 from users
where username=?`, user)
if err := row.Scan(&salt, &hash); err != nil {
return fmt.Errorf("User %s unknown", user)
}
if !bytes.Equal(saltHash(salt, pwd), hash) {
return fmt.Errorf("User %s invalid password", user)
}
return nil
}
 
func saltHash(salt []byte, pwd string) []byte {
h := md5.New()
h.Write(salt)
h.Write([]byte(pwd))
return h.Sum(nil)
}
 
func main() {
// demonstrate
db, err := connectDB()
defer db.Close()
createUser(db, "sam", "123")
err = authenticateUser(db, "sam", "123")
if err == nil {
fmt.Println("User sam authenticated")
}
 
// extra
fmt.Println()
// show contents of database
rows, _ := db.Query(`select username, pass_salt, pass_md5 from users`)
var user string
var salt, hash []byte
for rows.Next() {
rows.Scan(&user, &salt, &hash)
fmt.Printf("%s %x %x\n", user, salt, hash)
}
// try creating same user again
err = createUser(db, "sam", "123")
fmt.Println(err)
// try authenticating unknown user
err = authenticateUser(db, "pam", "123")
fmt.Println(err)
// try wrong password
err = authenticateUser(db, "sam", "1234")
fmt.Println(err)
// clear table to run program again
db.Exec(`truncate table users`)
}</lang>
{{out}}
<pre>
User sam authenticated
 
sam d5d1ef775a89f2b504dc808e66087f3d a939f77466e91527e748377cc14dfd66
User sam already exits
User pam unknown
User sam invalid password
</pre>
 
=={{header|Java}}==
1,707

edits