2단계: 로그인하는 고객
값: 주소와 카드
blueprint/petstore/model/entity.yml
# ---- value types ---------------------------------------------------------
Address:
meta: entity @embeddable -- 주소
fields:
street1: string(50)!
street2: string(50)
city: string(50)!
state: string(50)
zipcode: string(10)!
countryCode: string(2)!
CreditCard:
meta: entity @embeddable -- 결제 카드
fields:
creditCardNumber: string(30)! @writeonly # accepted, never sent back
creditCardType: CreditCardType!
creditCardExpDate: string(5)! # MM/YY
@embeddable 은 값 객체입니다: 식별자가 없고, 컬럼은 그것을 담는 엔티티의 테이블에 있으며, DTO 는 자기 검사와 함께
중첩 객체로 싣습니다. @writeonly 는 카드 번호를 받기만 하고 답하지 않습니다 - Ossie 로 내보낼 때도 그 컬럼은 빠집니다.
고객
blueprint/petstore/model/entity.yml
Customer:
# 가입은 누구나, 읽기·수정은 본인(과 관리자), 삭제는 관리자
meta: entity @root @editable @expose(20) @signin @owner(customerId) @access(read=owner, create=public, update=owner) @terms(member, 회원, 손님)
@Index(name="uk_ps_customer_login", columnList="login", unique="true") -- 고객
fields:
customerId: long @id @sequence
login: string(10)! @search(eq) @login
password: string(255)! @password # 저장은 해시로만, 응답·검색에 없음
firstName: string(50)! @search(like)
lastName: string(50)! @search(like)
telephone: string(30)
email: string(100) @email
dateOfBirth: date @past
role: UserRole @default(UserRole.USER) @access(admin) # 관리자만 바꿈
homeAddress: Address! @Embedded # 집 주소는 필수 (기본 배송지)
blueprint/petstore/model/enum.yml
UserRole:
meta: enum @db(code) @json(code) -- 사용자 권한
fields:
code: string(1) @code
label: string(20)
enum:
USER: U, User
ADMIN: A, Administrator
| 조각 | 효과 |
|---|---|
@owner(customerId) @access(read=owner, create=public, update=owner) | 가입은 누구나, 고객은 자기 행만 읽고 고침(남의 것은 404). delete 는 적지 않았으므로 관리자 |
@password | 모든 쓰기 경로에서 해시(PBKDF2). 응답·검색에 없음 |
@login + @password | 코어 서비스와 유스케이스에 authenticate(login, password) |
@signin | POST /api/petstore/customer/signin, POST .../signout, GET .../me - TypeScript 클라이언트에 signIn, signOut, me() |
role ... @access(admin) | 세션의 역할 - 관리자만 씀. 가입하며 "role":"A" 를 보내도 U 로 저장 |
@Index(... unique="true") | 이미 있는 로그인은 409 |
@email, @past | 형식이 틀린 이메일, 미래의 생일은 400 |
homeAddress: Address! @Embedded | 주소 필수. 주소의 필수 필드가 비면 400 |
여기서 @signin 이 생성되는 것은 그 행을 본인과 관리자만 바꿀 수 있기 때문입니다(update=owner 와 키를 가리키는
@owner) - 아니면 빌드가 경고하고 만들지 않습니다.
가입하고 바로 로그인
로그인은 생성된 API 가 합니다. 한 요청으로 가입 하고 로그인까지 하는 것은 이 상점의 선택이라 손으로 쓴 컨트롤러 하나입니다:
adapter/in/web/shop/AccountController.java (손으로 씀)
@RestController
@RequestMapping("/api/petstore/account")
public class AccountController {
private final CustomerUseCase customers;
public AccountController(CustomerUseCase customers) {
this.customers = customers;
}
/** A new customer, signed in. The service keeps the role out of a visitor's hands. */
@PostMapping("/signup")
@ResponseStatus(HttpStatus.CREATED)
public CustomerDTO signUp(@Valid @RequestBody CustomerDTO customer, HttpServletRequest request) {
customer.setCustomerId(null);
CustomerDTO created = customers.save(customer);
SessionCurrentUser.signIn(request, created.getCustomerId(), created.getRole().name());
return created;
}
}
데모 계정
DemoAccounts.java (손으로 씀, 줄임)
@Component
@ConditionalOnProperty(name = "petstore.demo-accounts", havingValue = "true")
class DemoAccounts implements ApplicationRunner {
/** As the application itself: only it may make an administrator. */
@Override
public void run(ApplicationArguments args) {
CurrentUser.runAsSystem(() -> {
create("admin", "Admin", "The Admin Alley", UserRole.ADMIN);
create("user", "User", "The User Boulevard", UserRole.USER);
});
}
// create(...) 는 CustomerService 로 CustomerDTO 를 저장 - 비밀번호는 다른 고객처럼 해시됨
}
공개 데모의 관리자는 xsko / xsko, 로컬은 admin / admin 입니다.
써 보기
# 로그인하고 세션 쿠키를 유지
curl -s -c jar -b jar -X POST https://petstore.elasticore.io/api/petstore/customer/signin \
-H 'Content-Type: application/json' -d '{"login":"user","password":"user"}'
curl -s -c jar -b jar https://petstore.elasticore.io/api/petstore/customer/me
curl -s -c jar -b jar -X POST https://petstore.elasticore.io/api/petstore/customer/signout
- 로그인은 비밀번호 없이 고객을 답합니다. 비밀번호가 틀리면 401
Wrong login or password. me는 방문자와signout뒤에 401 입니다.- 남의
GET /api/petstore/customer/{id}는 404 입니다.
다음: 주문.